﻿///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2023, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область ОписаниеПеременных

// Информация о текущем выполняемом фоновом задании
&НаКлиенте
Перем ВыполняемаяОперация; // см. ДлительныеОперации.ВыполнитьФункцию

&НаКлиенте
Перем ПредставлениеОперации; // Строка

&НаКлиенте
Перем СведенияОРезультатахУдаления; // см. УдалениеПомеченныхОбъектовСлужебныйКлиентСервер.НовыйСведенияОРезультатахУдаления

&НаКлиенте
Перем ОчередьЗаданийФормы; // Массив из Строка

&НаКлиенте
Перем РезультатПредыдущегоШага;

#КонецОбласти

#Область ОбработчикиСобытийФормы

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	Если Не Пользователи.ЭтоПолноправныйПользователь() Тогда
		ТекстОшибки = НСтр("ru = 'Недостаточно прав для выполнения операции.'");
		Возврат; // Отказ устанавливается в ПриОткрытии.
	КонецЕсли;
	
	Если ОбщегоНазначения.РазделениеВключено() И Не ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
		ТекстОшибки = НСтр("ru = 'Для удаления помеченных войдите в область данных.'");
		Возврат; // Отказ устанавливается в ПриОткрытии.
	КонецЕсли;
	
	Если Параметры.УдаляемыеОбъекты.Количество() > 0 Тогда
		НастроитьФормуДляРаботыКакСервис();
	Иначе
		НачатьПоискПомеченных_НастройкаФормы(ЭтотОбъект);
	КонецЕсли;
	
	Если Параметры.ОтборМетаданных.Количество() > 0 Тогда
		УстановитьПереданныйОтборМетаданных();
	КонецЕсли;
	
	ЭтоМобильныйКлиент = ОбщегоНазначения.ЭтоМобильныйКлиент();
	Если ЭтоМобильныйКлиент Тогда
		Элементы.ДеревоПомеченныхНаУдалениеНастроить.Видимость = Ложь;
		Элементы.ДеревоПомеченныхНаУдалениеИзменить.Видимость = Ложь;
		Элементы.НеУдаленныеИзменить.Видимость = Ложь;
		Элементы.Действия.Видимость = Ложь;
		Элементы.Назад.Видимость = Ложь;
	КонецЕсли;
	
	УстановитьСостояниеВыбораПомеченныхНаУдаление();
	УстановитьУсловноеОформление();	
	УстановитьСписокДействийМестИспользования(ЭтотОбъект);
	
	ТолькоПросмотр = Истина;
	
КонецПроцедуры

&НаСервере
Процедура ПриЗагрузкеДанныхИзНастроекНаСервере(Настройки)
	НастройкиДополнительныхРеквизитов = Настройки["ДополнительныеРеквизитыПомеченныхНаУдаления"];
	Если НастройкиДополнительныхРеквизитов <> Неопределено Тогда
		ЧислоДополнительныхРеквизитов = УдалениеПомеченныхОбъектовСлужебный.ЧислоДополнительныхРеквизитов(
			НастройкиДополнительныхРеквизитов);
		ДобавитьДополнительныеРеквизиты(1, ЧислоДополнительныхРеквизитов);
		УстановитьУсловноеОформление();
	КонецЕсли;
	
	НастройкиОтбора = Настройки["ОтборМетаданных"];
	Если ЗначениеЗаполнено(НастройкиОтбора) Тогда
		ОтборМетаданных = ОтборМетаданныхТолькоСуществующие(НастройкиОтбора);
		Элементы.НастроитьОтбор.Заголовок = ПредставлениеОтбораМетаданных(НастройкиОтбора);
	ИначеЕсли ЗначениеЗаполнено(Параметры.ОтборМетаданных) Тогда 
		ОтборМетаданных = Параметры.ОтборМетаданных;
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	Если ЗначениеЗаполнено(ТекстОшибки) Тогда
		ПоказатьПредупреждение(, ТекстОшибки);
		Отказ = Истина;
	КонецЕсли;
	
	Если УдалятьПриОткрытии Тогда
		ДобавитьЗадание(ЗаданияФормы().УдалениеПомеченных);
	Иначе	
		ДобавитьЗадание(ЗаданияФормы().ПоискПомеченных);
	КонецЕсли;
	ПодключитьОбработчикОжидания("ЗапуститьЗаданиеСОжиданием", 0.1, Истина);
КонецПроцедуры

&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
	Если ЗавершениеРаботы Тогда
		Возврат;
	КонецЕсли;
	
	Если ПоказатьДиалогПередЗакрытием Тогда
		Отказ = Истина;
		Обработчик = Новый ОписаниеОповещения("ПослеПодтвержденияОтменыЗадания", ЭтотОбъект);
		ТекстВопроса = НСтр("ru = 'Выполняется %1.
							|Прервать?'");
		Кнопки = Новый СписокЗначений;
		Кнопки.Добавить(КодВозвратаДиалога.Прервать);
		Кнопки.Добавить(КодВозвратаДиалога.Пропустить, НСтр("ru = 'Не прерывать'"));
		
		ПоказатьВопрос(Обработчик, 
			СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстВопроса, НРег(ПредставлениеОперации)),
		 	Кнопки, 60, КодВозвратаДиалога.Пропустить);
	ИначеЕсли УдалятьПриОткрытии Тогда 
		ОписаниеОповещенияОЗакрытии.ДополнительныеПараметры.Вставить("РезультатЗакрытия", СведенияОРезультатахУдаления);
	КонецЕсли;
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийЭлементовШапкиФормы

&НаКлиенте
Процедура СсылкаПодробнееНажатие(Элемент)
	Если ЭтоОшибкаУстановкиМонопольногоРежима(ПодробныйТекстОшибкиФоновогоЗадания) Тогда
		ОткрытьФормуЗавершенияРаботыПользователей();
	Иначе	
		ТекстОшибки = ?(Элемент.Имя = Элементы.ПодробнееОшибкаФоновогоЗадания.Имя, ПодробныйТекстОшибкиФоновогоЗадания, ПодробныйТекстОшибки);
		СтандартныеПодсистемыКлиент.ПоказатьПодробнуюИнформацию(Неопределено, ТекстОшибки);
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ОтменитьОперацию(Команда)
	ОтменитьОперациюСервер(ВыполняемаяОперация);
	ОчиститьОчередьЗаданийФормы();
	
	Если ТекущееЗадание().Имя = "ВыполнениеДополнительнойОбработки" Тогда
		УстановитьСостояниеНеуспешноеУдаление();
	Иначе
		УстановитьСостояниеВыбораПомеченныхНаУдаление();
	КонецЕсли;
	
	ПоказатьДиалогПередЗакрытием = Ложь;
	ВыполняемаяОперация = Неопределено;
	Если УдалятьПриОткрытии Тогда
		Закрыть();
	КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ОтменитьОперациюСервер(ВыполняемаяОперация)
	Если ВыполняемаяОперация = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	ДлительныеОперации.ОтменитьВыполнениеЗадания(ВыполняемаяОперация.ИдентификаторЗадания);
	УдалениеПомеченныхОбъектовСлужебный.СнятьБлокировкуИспользованияУдаляемыхОбъектов(УникальныйИдентификатор);
	УстановитьМонопольныйРежимНаСервере(Ложь);
КонецПроцедуры

&НаКлиенте
Процедура КВыборуОбъектов(Команда)
	Оповещение = Новый ОписаниеОповещения("КВыборуОбъектовЗавершение", ЭтотОбъект);
	Если ТаблицаДействий.Количество() > 0 Тогда
		ПоказатьВопрос(Оповещение, 
			НСтр("ru='Не завершено удаление объектов.
			|Вернуться к списку помеченных на удаление?'"),
			РежимДиалогаВопрос.ДаНет);
	Иначе
		ОбновитьДеревоПомеченныхНаУдаление();
		УстановитьСостояниеВыбораПомеченныхНаУдаление();
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура КВыборуОбъектовЗавершение(Результат, ДополнительныеПараметры) Экспорт
	ОбновитьДеревоПомеченныхНаУдаление();
	Если Результат = КодВозвратаДиалога.Да Тогда
		ТаблицаДействий.Очистить();
		УстановитьСостояниеВыбораПомеченныхНаУдаление();
	КонецЕсли;
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийЭлементовТаблицыФормыДеревоПомеченныхНаУдаление

&НаКлиенте
Процедура ДеревоПомеченныхНаУдалениеПометкаПриИзменении(Элемент)
	ТекущиеДанные = Элементы.ДеревоПомеченныхНаУдаление.ТекущиеДанные;
	Если ТекущиеДанные.Пометка = 2 Тогда
		ТекущиеДанные.Пометка = 0;
	КонецЕсли;
	
	ДеревоПомеченныхНаУдалениеУстановитьПометкуВСписке(ТекущиеДанные, ТекущиеДанные.Пометка, Истина);
КонецПроцедуры

&НаКлиенте
Процедура ДеревоПомеченныхНаУдалениеВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;
	ПоказатьОбъектТаблицы(Элемент);
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийЭлементовТаблицыФормыНеУдаленные

&НаКлиенте
Процедура НеУдаленныеПриАктивизацииСтроки(Элемент)
	ПодключитьОбработчикОжидания("ПоказатьСвязиНеУдаленныхНаКлиенте", 0.1, Истина);
КонецПроцедуры

&НаКлиенте
Процедура НеУдаленныеПередНачаломИзменения(Элемент, Отказ)
	Отказ = Истина;
	ПоказатьОбъектТаблицы(Элемент);
КонецПроцедуры

&НаКлиенте
Процедура НеУдаленныеВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;
	ПоказатьОбъектТаблицы(Элемент);
КонецПроцедуры

&НаКлиенте
Процедура НеУдаленныеПредставлениеОткрытие(Элемент, СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;
	ПоказатьОбъектТаблицы(Элемент);
КонецПроцедуры

&НаКлиенте
Процедура СвязиНеУдаленныхВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
	Если Поле.Имя <> Элементы.СвязиНеУдаленныхДействие.Имя Тогда
		СтандартнаяОбработка = Ложь;
		ПоказатьОбъектТаблицы(Элемент);
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура МестаИспользованияНеудаленныхОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
	УстановитьЗаменитьНаПродолжение(ВыбранноеЗначение);
КонецПроцедуры

&НаКлиенте
Процедура СвязиНеУдаленныхДействиеПриИзменении(Элемент)
	ТекущиеДанные = Элементы.МестаИспользованияНеудаленных.ТекущиеДанные;
	ВыбранноеЗначение = ТекущиеДанные.ДействиеПредставление;
	
	Если НЕ ЗначениеЗаполнено(ВыбранноеЗначение) Тогда
		
		Если ТекущиеДанные.Действие = "ЗаменитьСсылку" Тогда
			Для Каждого Элемент Из МестаИспользованияНеудаленных.ПолучитьЭлементы() Цикл
				Элемент.Действие = Неопределено;
			КонецЦикла;	
			
			Фильтр = Новый Структура("Источник", ТекущиеДанные.УдаляемыйСсылка);
			Действия = ТаблицаДействий.НайтиСтроки(Фильтр);
			Для Каждого Действие Из Действия Цикл
				ТаблицаДействий.Удалить(Действие);
			КонецЦикла;
		Иначе			
			ТекущиеДанные.Действие = Неопределено;
			
			Фильтр = Новый Структура("ОбнаруженныйСсылка", ТекущиеДанные.ОбнаруженныйСсылка);
			Действия = ТаблицаДействий.НайтиСтроки(Фильтр);
			Для Каждого Действие Из Действия Цикл
				ТаблицаДействий.Удалить(Действие);
			КонецЦикла;
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура СвязиНеУдаленныхДействиеОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;
	
	ТекущиеДанные = Элементы.МестаИспользованияНеудаленных.ТекущиеДанные;
	ТекущиеДанные.ДействиеПредставление = "";
	
	ПриВыбореДействияМестаИспользования(ВыбранноеЗначение, ТекущиеДанные);
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиКомандФормы

&НаКлиенте
Процедура Обновить(Команда)
	Если ВыполняемаяОперация = Неопределено Тогда
		ЗапуститьЗадание(ЗаданияФормы().ПоискПомеченных);
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьДействияИУдалить(Команда)
	ОбновитьДеревоПомеченныхНаУдаление();
	СведенияОВыбранныхОбъектах = КоличествоВыбранныхОбъектов();
	ОбщееКоличествоВыбранных = СведенияОВыбранныхОбъектах.КоличествоВыбранных;
	Если ОбщееКоличествоВыбранных = 0 Тогда
		ТекстПредупреждения = НСтр("ru='Необходимо выбрать хотя бы один элемент для удаления.'");
		ПоказатьПредупреждение(, ТекстПредупреждения);
		Возврат;
	КонецЕсли;
	ДобавитьЗадание(ЗаданияФормы().ВыполнениеДополнительнойОбработки);
	ДобавитьЗадание(ЗаданияФормы().УдалениеПомеченных);
	ЗапуститьЗадание();
КонецПроцедуры

&НаКлиенте
Процедура НеУдаленныеИзменить(Команда)
	Если НЕ ОбщегоНазначенияКлиентСервер.ЕстьРеквизитИлиСвойствоОбъекта(ТекущийЭлемент, "ТекущиеДанные") Тогда
		Возврат;
	КонецЕсли;

	ПоказатьОбъектТаблицы(ТекущийЭлемент);	
КонецПроцедуры

&НаКлиенте
Процедура ДеревоПомеченныхНаУдалениеУстановитьВсе(Команда)
	ЭлементыСписка = ДеревоПомеченныхНаУдаление.ПолучитьЭлементы();
	
	Для Каждого Элемент Из ЭлементыСписка Цикл
		ДеревоПомеченныхНаУдалениеУстановитьПометкуВСписке(Элемент, Истина, Истина);
		Родитель = Элемент.ПолучитьРодителя();
		Если Родитель = Неопределено Тогда
			ДеревоПомеченныхНаУдалениеПроверитьРодителя(Элемент)
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура ДеревоПомеченныхНаУдалениеСнятьВсе(Команда)
	ЭлементыСписка = ДеревоПомеченныхНаУдаление.ПолучитьЭлементы();
	
	Для Каждого Элемент Из ЭлементыСписка Цикл
		ДеревоПомеченныхНаУдалениеУстановитьПометкуВСписке(Элемент, Ложь, Истина);
		Родитель = Элемент.ПолучитьРодителя();
		Если Родитель = Неопределено Тогда
			ДеревоПомеченныхНаУдалениеПроверитьРодителя(Элемент)
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура ДеревоПомеченныхНаУдалениеИзменить(Команда)
	ПоказатьОбъектТаблицы(Элементы.ДеревоПомеченныхНаУдаление);
КонецПроцедуры

&НаКлиенте
Процедура ДеревоПомеченныхНаУдалениеОбновить(Команда)
	ЗапуститьЗадание(ЗаданияФормы().ПоискПомеченных);
КонецПроцедуры

&НаКлиенте
Процедура УстановитьУдалить(Команда)
	Для Каждого ИдентификаторСтроки Из Элементы.МестаИспользованияНеудаленных.ВыделенныеСтроки Цикл
		ВыделеннаяСтрока = МестаИспользованияНеудаленных.НайтиПоИдентификатору(ИдентификаторСтроки);
		ПриВыбореДействияМестаИспользования("Удалить", ВыделеннаяСтрока);
	КонецЦикла;
	
	ЗаполнитьМестаИспользованияНеудаленныхОбъектов(ЭтотОбъект);
	СтандартныеПодсистемыКлиент.РазвернутьУзлыДерева(ЭтотОбъект, "МестаИспользованияНеудаленных", "*", Истина);
КонецПроцедуры

&НаКлиенте
Процедура УстановитьЗаменитьНа(Команда)
	ТекущиеДанные = Элементы.МестаИспользованияНеудаленных.ТекущиеДанные;
	
	Если ТекущиеДанные = Неопределено Тогда
		Состояние(НСтр("ru='Для выбранной строки нельзя указать действие.'"),,,БиблиотекаКартинок.Предупреждение32);
		Возврат;
	КонецЕсли;
	
	Если ТекущиеДанные.ОсновнаяПричина Тогда
		ПутьКФорме = ИмяМетаданных(ТекущиеДанные.УдаляемыйСсылка) + ".ФормаВыбора";
		ПараметрыФормы = Новый Структура;
		ПараметрыФормы.Вставить("РежимВыбора", Истина);
		ОткрытьФорму(ПутьКФорме, ПараметрыФормы, Элементы.МестаИспользованияНеудаленных, , , , , РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
	Иначе
		Состояние(НСтр("ru='Для выбранной строки нельзя указать действие.'"),,,БиблиотекаКартинок.Предупреждение32);
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура УстановитьЗаменитьНаПродолжение(Результат)
	ТекущиеДанные = Элементы.МестаИспользованияНеудаленных.ТекущиеДанные;
	
	Для Каждого ИдентификаторСтроки Из Элементы.МестаИспользованияНеудаленных.ВыделенныеСтроки Цикл
		ВыделеннаяСтрока = МестаИспользованияНеудаленных.НайтиПоИдентификатору(ИдентификаторСтроки);
		
		Если ВыделеннаяСтрока.УдаляемыйСсылка <> ТекущиеДанные.УдаляемыйСсылка Тогда
			Продолжить;
		КонецЕсли;
		
		Если Результат = Неопределено Тогда
			ЗарегистрироватьДействиеМестаИспользования(ВыделеннаяСтрока, Неопределено);
		Иначе
			Если ВыделеннаяСтрока.ОсновнаяПричина Тогда
				ЗарегистрироватьДействиеМестаИспользования(ВыделеннаяСтрока, "ЗаменитьСсылку", Результат);
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
	Для Каждого ВыделеннаяСтрока Из МестаИспользованияНеудаленных.ПолучитьЭлементы() Цикл
		Если ВыделеннаяСтрока.ОсновнаяПричина 
				И ВыделеннаяСтрока.Действие <> "Удалить" Тогда
			ЗарегистрироватьДействиеМестаИспользования(ВыделеннаяСтрока, "ЗаменитьСсылку", Результат);
		КонецЕсли;
	КонецЦикла;
	
	ЗаполнитьМестаИспользованияНеудаленныхОбъектов(ЭтотОбъект);
	СтандартныеПодсистемыКлиент.РазвернутьУзлыДерева(ЭтотОбъект, "МестаИспользованияНеудаленных", "*", Истина);
КонецПроцедуры

&НаКлиенте
Процедура Настроить(Команда)
	ОповещениеОЗакрытии = Новый ОписаниеОповещения("НастроитьПродолжение", ЭтотОбъект);
	
	ПараметрыФормы = Новый Структура("АдресНастроек", НастройкиУдаленияПомеченных());
	ОткрытьФорму("Обработка.УдалениеПомеченныхОбъектов.Форма.НастройкиУдаленияОбъектов", ПараметрыФормы, ЭтотОбъект, , , ,
		ОповещениеОЗакрытии, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецПроцедуры

&НаСервере
Функция НастройкиУдаленияПомеченных()
	Настройки = Новый Структура;
	Настройки.Вставить("РежимУдаления", РежимУдаления);
	Настройки.Вставить("ВыбранныеРеквизиты", ДополнительныеРеквизитыПомеченныхНаУдаления.Выгрузить());
	Возврат ПоместитьВоВременноеХранилище(Настройки, УникальныйИдентификатор);
КонецФункции

&НаКлиенте
Процедура НастроитьПродолжение(Результат, ДополнительныеПараметры) Экспорт
	Если Результат = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	ТребуетсяОбновлениеПомеченныхНаУдаление = НастроитьПродолжениеСервер(Результат);
	Если ТребуетсяОбновлениеПомеченныхНаУдаление Тогда
		ЗапуститьЗадание(ЗаданияФормы().ПоискПомеченных);
	КонецЕсли;
КонецПроцедуры

&НаСервере
Функция НастроитьПродолжениеСервер(АдресНастроек)
	Настройки = ПолучитьИзВременногоХранилища(АдресНастроек);
	УдалитьИзВременногоХранилища(АдресНастроек);
	РежимУдаления = Настройки.РежимУдаления;

	НастройкиИзменились = НастройкиИзменились(Настройки.ВыбранныеРеквизиты);

	ТекущееЧислоДополнительныхРеквизитов = УдалениеПомеченныхОбъектовСлужебный.ЧислоДополнительныхРеквизитов(
		ДополнительныеРеквизитыПомеченныхНаУдаления.Выгрузить());
	НовоеЧислоДополнительныхРеквизитов = УдалениеПомеченныхОбъектовСлужебный.ЧислоДополнительныхРеквизитов(Настройки.ВыбранныеРеквизиты);
	ТекущееЧислоСозданныхРеквизитов = ТекущееЧислоСозданныхРеквизитов(ТекущееЧислоДополнительныхРеквизитов, НовоеЧислоДополнительныхРеквизитов);

	Если ТекущееЧислоСозданныхРеквизитов < НовоеЧислоДополнительныхРеквизитов Тогда
		ЧислоДобавляемыхРеквизитов = НовоеЧислоДополнительныхРеквизитов - ТекущееЧислоСозданныхРеквизитов;
		ДобавитьДополнительныеРеквизиты(ТекущееЧислоСозданныхРеквизитов + 1, ЧислоДобавляемыхРеквизитов);
	КонецЕсли;
	
	Если ТекущееЧислоДополнительныхРеквизитов < ТекущееЧислоСозданныхРеквизитов 
		И ТекущееЧислоДополнительныхРеквизитов < НовоеЧислоДополнительныхРеквизитов Тогда
		
		УстановитьВидимостьДополнительныхРеквизитов(ТекущееЧислоДополнительныхРеквизитов+1, ТекущееЧислоСозданныхРеквизитов, Истина);
	КонецЕсли;

	Если ТекущееЧислоДополнительныхРеквизитов > НовоеЧислоДополнительныхРеквизитов Тогда
		УстановитьВидимостьДополнительныхРеквизитов(НовоеЧислоДополнительныхРеквизитов+1,
			ТекущееЧислоДополнительныхРеквизитов, Ложь);
	КонецЕсли;
	
	ДополнительныеРеквизитыПомеченныхНаУдаления.Загрузить(Настройки.ВыбранныеРеквизиты);
	
	УстановитьУсловноеОформление();
	
	Возврат НовоеЧислоДополнительныхРеквизитов > ТекущееЧислоДополнительныхРеквизитов ИЛИ НастройкиИзменились;
КонецФункции

&НаКлиенте
Процедура УдалитьВыбранные(Команда)
	
	СведенияОВыбранныхОбъектах = КоличествоВыбранныхОбъектов();
	ОбщееКоличествоВыбранных = СведенияОВыбранныхОбъектах.КоличествоВыбранных;
	Если ОбщееКоличествоВыбранных = 0 Тогда
		ТекстВопроса = НСтр("ru='Необходимо выбрать хотя бы один элемент для удаления.'");
		ПоказатьПредупреждение(, ТекстВопроса);
		Возврат;
	ИначеЕсли ОбщееКоличествоВыбранных = 1 Тогда
		ТекстВопроса = НСтр("ru='Удалить элемент, помеченный на удаление?'");
	ИначеЕсли ОбщееКоличествоВыбранных = СведенияОВыбранныхОбъектах.КоличествоВсего Тогда
		ТекстВопроса = НСтр("ru='Удалить все элементы, помеченные на удаление?'");
	Иначе
		ТекстВопроса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru='Удалить элементы, помеченные на удаление (%1)?'"),
			ОбщееКоличествоВыбранных);
	КонецЕсли;
	
	ОповещениеПодтверждениеУдалитьВсе = Новый ОписаниеОповещения("ПриПодтвержденииУдалить",
		ЭтотОбъект, СведенияОВыбранныхОбъектах);
	ПоказатьВопрос(ОповещениеПодтверждениеУдалитьВсе, ТекстВопроса, РежимДиалогаВопрос.ДаНет);
	
КонецПроцедуры

&НаКлиенте
Процедура НастроитьОтбор(Команда)
	КоллекцияВыбираемыхОбъектов = Новый СписокЗначений();
	
	КоллекцияВыбираемыхОбъектов.Добавить("Справочники");
	КоллекцияВыбираемыхОбъектов.Добавить("Документы");
	КоллекцияВыбираемыхОбъектов.Добавить("ПланыВидовХарактеристик");
	КоллекцияВыбираемыхОбъектов.Добавить("ПланыСчетов");
	КоллекцияВыбираемыхОбъектов.Добавить("ПланыСчетов");
	КоллекцияВыбираемыхОбъектов.Добавить("ПланыВидовРасчета");
	КоллекцияВыбираемыхОбъектов.Добавить("БизнесПроцессы");
	КоллекцияВыбираемыхОбъектов.Добавить("Задачи");
	
	ПараметрыФормы = Новый Структура;
	ПараметрыФормы.Вставить("КоллекцииВыбираемыхОбъектовМетаданных", КоллекцияВыбираемыхОбъектов);
	ПараметрыФормы.Вставить("ОбластиПоиска", ОтборМетаданных);
	ПараметрыФормы.Вставить("ТолькоПодсистемыСКИ", Истина);
	
	ОповещениеОЗакрытии = Новый ОписаниеОповещения("НастроитьОтборЗавершение", ЭтотОбъект);
	ОткрытьФорму("Обработка.УдалениеПомеченныхОбъектов.Форма.ВыборОбъектовМетаданныхПоПодсистемам", ПараметрыФормы, ЭтотОбъект, , , , ОповещениеОЗакрытии,
		РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецПроцедуры

&НаКлиенте
Процедура РазвернутьСтрокиДереваПомеченных(Команда)
	СтандартныеПодсистемыКлиент.РазвернутьУзлыДерева(ЭтотОбъект, "ДеревоПомеченныхНаУдаление");
КонецПроцедуры

&НаКлиенте
Процедура СвернутьСтрокиДереваВыбораПомеченных(Команда)
	ВсеСтроки = Элементы.ДеревоПомеченныхНаУдаление;
	Для Каждого ДанныеСтроки Из ДеревоПомеченныхНаУдаление.ПолучитьЭлементы() Цикл 
		ВсеСтроки.Свернуть(ДанныеСтроки.ПолучитьИдентификатор());
	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура УстановитьСнятьПометкуУдаления(Команда)
	
	СсылкиДляОбработки = Новый Массив;
	ПредставлениеПоследнегоВыбранного = "";
	КоличествоЭлементовСоСнятойПометкой = 0;
	Для каждого ВыделеннаяСтрока Из Элементы.НеУдаленные.ВыделенныеСтроки Цикл
		Данные = Элементы.НеУдаленные.ДанныеСтроки(ВыделеннаяСтрока);
		Если ТипЗнч(Данные.УдаляемыйСсылка) <> Тип("Строка") Тогда
			СсылкиДляОбработки.Добавить(Данные.УдаляемыйСсылка);
			ПредставлениеПоследнегоВыбранного = Данные.Представление;
		КонецЕсли;
		
		Если ЭлементыБезПометкиУдаления.НайтиПоЗначению(Данные.УдаляемыйСсылка) <> Неопределено Тогда
			КоличествоЭлементовСоСнятойПометкой = КоличествоЭлементовСоСнятойПометкой + 1;
		КонецЕсли;
	КонецЦикла;
	
	УстанавливатьПометку = СсылкиДляОбработки.Количество() = КоличествоЭлементовСоСнятойПометкой
							И КоличествоЭлементовСоСнятойПометкой <> 0;
	
	Обработчик = Новый ОписаниеОповещения("УстановитьСнятьПометкуУдаленияПродолжение", ЭтотОбъект, СсылкиДляОбработки);
	Если СсылкиДляОбработки.Количество() = 1 Тогда
		Если УстанавливатьПометку Тогда
			ТекстВопроса = НСтр("ru = 'Пометить ""%1"" на удаление?'");
		Иначе
			ТекстВопроса = НСтр("ru = 'Снять с ""%1"" пометку на удаление?'");
		КонецЕсли;
		ТекстВопроса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстВопроса, ПредставлениеПоследнегоВыбранного);
	Иначе
		Если УстанавливатьПометку Тогда
			ТекстВопроса = НСтр("ru = 'Пометить выделенные объекты (%1) на удаление?'");
		Иначе
			ТекстВопроса = НСтр("ru = 'Снять с выделенных объектов (%1) пометку на удаление?'");
		КонецЕсли;
		ТекстВопроса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстВопроса, Формат(СсылкиДляОбработки.Количество(), "ЧН=0; ЧГ="));
	КонецЕсли;
	
	ПоказатьВопрос(Обработчик, ТекстВопроса, РежимДиалогаВопрос.ДаНет, 60, КодВозвратаДиалога.Нет);
	
КонецПроцедуры

&НаКлиенте
Процедура УстановитьСнятьПометкуУдаленияПродолжение(Результат, СсылкиДляОбработки) Экспорт

	Если Результат = КодВозвратаДиалога.Нет Тогда
		Возврат;
	КонецЕсли;
	
	Изменения = Неопределено;
	Попытка
		Изменения = УстановитьСнятьПометкуУдаленияНаСервере(СсылкиДляОбработки);
	Исключение
		ТекстОшибки = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
		ТекстОшибки = НСтр("ru='Не удалось изменить пометку удаления по причине:'")
			+ Символы.ПС + ТекстОшибки;
		ПоказатьПредупреждение(, ТекстОшибки);
	КонецПопытки;
	
	Если Изменения <> Неопределено Тогда
		СтандартныеПодсистемыКлиент.ОповеститьФормыОбИзменении(Изменения);
	КонецЕсли;	
	СтандартныеПодсистемыКлиент.РазвернутьУзлыДерева(ЭтотОбъект, "НеУдаленные", "*", Истина);	

КонецПроцедуры

&НаСервере
Функция УстановитьСнятьПометкуУдаленияНаСервере(Ссылки)
	
	Попытка
		Изменения = УдалениеПомеченныхОбъектовСлужебный.СнятьУстановитьПометкуУдаления(Ссылки);
	Исключение
		ЗаписьЖурналаРегистрации(
			НСтр("ru='Удаление помеченных.Установка / снятие пометки удаления'", ОбщегоНазначения.КодОсновногоЯзыка()),
			УровеньЖурналаРегистрации.Ошибка,,, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		ВызватьИсключение;
	КонецПопытки;
	
	Результат = Новый Массив;
	ДеревоНеудаленные = РеквизитФормыВЗначение("НеУдаленные");
	ИнформацияОТипах = УдалениеПомеченныхОбъектовСлужебный.ИнформацияОТипах(Изменения.ВыгрузитьКолонку("Ссылка"));

	Для каждого Изменение Из Изменения Цикл
		
		ИнформацияОТипе = ИнформацияОТипах[ТипЗнч(Изменение.Ссылка)]; // см. УдалениеПомеченныхОбъектовСлужебный.ИнформацияОТипе
		СтрокиМетаданных = ДеревоНеудаленные.Строки.НайтиСтроки(
			Новый Структура("УдаляемыйСсылка", ИнформацияОТипе.ПолноеИмя))[0].Строки;
		Данные = СтрокиМетаданных.НайтиСтроки(Новый Структура("УдаляемыйСсылка", Изменение.Ссылка))[0];
		
		Данные.НомерКартинки = УдалениеПомеченныхОбъектовСлужебный.НомерКартинки(Изменение.Ссылка,
			ИнформацияОТипе.Ссылочный, ИнформацияОТипе.Вид,
			?(Изменение.НовоеЗначениеПометкиУдаления = Истина, "Удален", Неопределено));
		Результат.Добавить(Изменение.Ссылка);

		Если НЕ Изменение.НовоеЗначениеПометкиУдаления Тогда
			ЭлементыБезПометкиУдаления.Добавить(Изменение.Ссылка);
		Иначе
			ЭлементСписка = ЭлементыБезПометкиУдаления.НайтиПоЗначению(Изменение.Ссылка);
			Если ЭлементСписка <> Неопределено Тогда
				ЭлементыБезПометкиУдаления.Удалить(ЭлементСписка);
			КонецЕсли;
		КонецЕсли;

	КонецЦикла;

	ЗначениеВРеквизитФормы(ДеревоНеудаленные, "НеУдаленные");	
	Возврат СтандартныеПодсистемыСервер.ПодготовитьОповещениеФормОбИзменении(Результат);
	
КонецФункции

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

#Область СостоянияФормы

&НаСервере
Процедура УстановитьСостояниеВыбораПомеченныхНаУдаление()
	Элементы.КоманднаяПанельФормы.Доступность = Истина;
	Элементы.СостояниеВыполняется.Видимость = Ложь;
	Элементы.СтраницыИнформация.Доступность = Истина;
	
	Элементы.СтраницыИнформация.ТекущаяСтраница = Элементы.СтраницаВыборОбрабатываемыхОбъектов;
	Элементы.СтраницыОтображениеСостояния.Видимость = Ложь;
	Элементы.СтраницыИнформация.ТолькоПросмотр = Ложь;
	Элементы.ГруппаАктивныПослеПоискаПомеченные.Доступность = ДеревоПомеченныхНаУдаление.ПолучитьЭлементы().Количество() > 0;
	
	Элементы.КоманднаяПанельПоискПомеченных.Видимость = Истина;
	Элементы.КоманднаяПанельОбработкаОшибок.Видимость = Ложь;
	
	Элементы.ГруппаНастройкиОтбораПоиска.Доступность = Истина;
	Элементы.ПредставлениеПрогресса.Видимость = Ложь;
	Элементы.ДеревоПомеченныхНаУдалениеУдалитьВыбранные.КнопкаПоУмолчанию = Истина;
	Элементы.СтрокаПоискаНаУдаление.Видимость = Истина;
КонецПроцедуры

&НаСервере
Процедура УстановитьСостояниеВыбораПомеченныхНаУдалениеСПанельюСостояния()
	Элементы.КоманднаяПанельФормы.Доступность = Истина;
	Элементы.СостояниеВыполняется.Видимость = Истина;
	Элементы.СтраницыИнформация.Доступность = Истина;
	
	Элементы.СтраницыИнформация.ТекущаяСтраница = Элементы.СтраницаВыборОбрабатываемыхОбъектов;
	Элементы.СтраницыОтображениеСостояния.Видимость = Истина;
	Элементы.СтраницыИнформация.ТолькоПросмотр = Ложь;
	
	Элементы.КоманднаяПанельПоискПомеченных.Видимость = Истина;
	Элементы.КоманднаяПанельОбработкаОшибок.Видимость = Ложь;
	
	Элементы.ГруппаНастройкиОтбораПоиска.Доступность = Истина;
	Элементы.ПредставлениеПрогресса.Видимость = Ложь;
	Элементы.ДеревоПомеченныхНаУдалениеУдалитьВыбранные.КнопкаПоУмолчанию = Истина;
	Элементы.ГруппаАктивныПослеПоискаПомеченные.Доступность = ДеревоПомеченныхНаУдаление.ПолучитьЭлементы().Количество() > 0;
	Элементы.СтрокаПоискаНаУдаление.Видимость = Ложь;
КонецПроцедуры

&НаСервере
Процедура УстановитьСостояниеНеуспешноеУдаление()
	Элементы.КоманднаяПанельФормы.Доступность = Истина;
	Элементы.СостояниеВыполняется.Видимость = Ложь;
	Элементы.СтраницыИнформация.Доступность = Истина;
	Элементы.СтраницыИнформация.Видимость = Истина;
	
	Элементы.СтраницыИнформация.ТекущаяСтраница = Элементы.СтраницаПричиныНевозможностиУдаления;
	Элементы.СтраницыОтображениеСостояния.Видимость = Ложь;
	Элементы.СтраницыИнформация.ТолькоПросмотр = Ложь;
	Элементы.ГруппаАктивныПослеПоискаПомеченные.ТолькоПросмотр = Ложь;
	
	Элементы.КоманднаяПанельПоискПомеченных.Видимость = Ложь;
	Элементы.КоманднаяПанельОбработкаОшибок.Видимость = Истина;
	
	Элементы.ГруппаНастройкиОтбораПоиска.Доступность = Ложь;
	Элементы.ПредставлениеПрогресса.Видимость = Ложь;
	Элементы.КоманднаяПанельФормы.Видимость = Истина;
	Элементы.ВыполнитьДействияИУдалить.КнопкаПоУмолчанию = Истина;
	Элементы.СсылкаПодробнее.Видимость = Ложь;
	Элементы.СтрокаПоискаНаУдаление.Видимость = Ложь;
КонецПроцедуры

&НаСервере
Процедура УстановитьСостояниеНеуспешноеУдалениеСПанельюСостояния()
	Элементы.КоманднаяПанельФормы.Доступность = Истина;
	Элементы.СостояниеВыполняется.Видимость = Истина;
	Элементы.СтраницыИнформация.Доступность = Истина;
	Элементы.СтраницыИнформация.Видимость = Истина;
	
	Элементы.СтраницыИнформация.ТекущаяСтраница = Элементы.СтраницаПричиныНевозможностиУдаления;
	Элементы.СтраницыОтображениеСостояния.Видимость = Истина;
	Элементы.СтраницыИнформация.ТолькоПросмотр = Ложь;
	Элементы.ГруппаАктивныПослеПоискаПомеченные.ТолькоПросмотр = Ложь;
	
	Элементы.КоманднаяПанельПоискПомеченных.Видимость = Ложь;
	Элементы.КоманднаяПанельОбработкаОшибок.Видимость = Истина;
	
	Элементы.ГруппаНастройкиОтбораПоиска.Доступность = Ложь;
	Элементы.ПредставлениеПрогресса.Видимость = Ложь;
	Элементы.КоманднаяПанельФормы.Видимость = Истина;
	Элементы.ВыполнитьДействияИУдалить.КнопкаПоУмолчанию = Истина;
	
	Если ЭтоМобильныйКлиент Тогда
		Элементы.ГруппаНеУдаленные.Видимость = Ложь;
	КонецЕсли;
	Элементы.СсылкаПодробнее.Видимость = Ложь;
	Элементы.СтрокаПоискаНаУдаление.Видимость = Ложь;
КонецПроцедуры

#КонецОбласти

// Параметры:
//   Ссылка - ЛюбаяСсылка
// Возвращаемое значение:
//   Строка
//
&НаСервереБезКонтекста
Функция ИмяМетаданных(Ссылка)
	Возврат Ссылка.Метаданные().ПолноеИмя();
КонецФункции

&НаКлиенте
Процедура ОбновитьДеревоПомеченныхНаУдаление()
	ОбновитьДеревоПомеченныхНаУдалениеНаСервере();
	
	
КонецПроцедуры

&НаСервере
Процедура ОбновитьДеревоПомеченныхНаУдалениеНаСервере()

	ПомеченныеНаУдаление = РеквизитФормыВЗначение("ДеревоПомеченныхНаУдаление");
	Для каждого ЭлементСписка Из ЭлементыБезПометкиУдаления Цикл
	
		ВидМетаданных = ПомеченныеНаУдаление.Строки.НайтиСтроки(
							Новый Структура("УдаляемыйСсылка", ВРег(ИмяМетаданных(ЭлементСписка.Значение))))[0];
		УдаляемыеСтроки = ВидМетаданных.Строки.НайтиСтроки(
							Новый Структура("УдаляемыйСсылка", ЭлементСписка.Значение));
		Для каждого СтрокаДерева Из УдаляемыеСтроки Цикл
			ВидМетаданных.Строки.Удалить(СтрокаДерева);
		КонецЦикла;
		
		Если ВидМетаданных.Строки.Количество() = 0 Тогда
			ПомеченныеНаУдаление.Строки.Удалить(ВидМетаданных);
		КонецЕсли;
	
	КонецЦикла;
	
	Для каждого УзелТипа Из ПомеченныеНаУдаление.Строки Цикл
		ЭлементыУзла = УзелТипа.Строки;
		УзелТипа.Пометка = ЗначениеПометкиЭлементов(ЭлементыУзла);
		Если УзелТипа.Строки.Количество() > 0 Тогда
			ОбъектМетаданныхУзла = УзелТипа.Строки[0].УдаляемыйСсылка.Метаданные();
			УзелТипа.Представление = ОбщегоНазначения.ПредставлениеСписка(ОбъектМетаданныхУзла) + " (" + УзелТипа.Строки.Количество() + ")";
		КонецЕсли;
	КонецЦикла;
	
	ЗначениеВРеквизитФормы(ПомеченныеНаУдаление, "ДеревоПомеченныхНаУдаление");
	ЭлементыБезПометкиУдаления.Очистить();

КонецПроцедуры

#Область Настройки

&НаСервере
Функция НастройкиИзменились(ВыбранныеРеквизиты)
	Результат = Ложь;
	
	ТаблицаСравнения = УдалениеПомеченныхОбъектовСлужебный.ОбъединениеТаблиц(
		ВыбранныеРеквизиты,
		ДополнительныеРеквизитыПомеченныхНаУдаления.Выгрузить());
		
	ТаблицаСравнения.Колонки.Добавить("Число", Новый ОписаниеТипов("Число"));
	ТаблицаСравнения.ЗаполнитьЗначения(1,"Число");
	ТаблицаСравнения.Свернуть("Метаданные, Реквизит", "Число");
	Для Каждого Элемент Из ТаблицаСравнения Цикл
		Если Элемент.Число <> 2 Тогда
			Результат = Истина;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	
	Возврат Результат;		
КонецФункции

&НаСервере
Функция ТекущееЧислоСозданныхРеквизитов(ТекущееЧислоДополнительныхРеквизитов, НовоеЧислоДополнительныхРеквизитов)
	Результат = ТекущееЧислоДополнительныхРеквизитов;
	
	Для Сч = ТекущееЧислоДополнительныхРеквизитов + 1 По НовоеЧислоДополнительныхРеквизитов Цикл
		Если Элементы.Найти("ДеревоПомеченныхНаУдалениеРеквизит"+Сч) <> Неопределено Тогда
			Результат = Сч;
		КонецЕсли;
	КонецЦикла;
	
	Возврат Результат;
КонецФункции

&НаСервере
Процедура УстановитьВидимостьДополнительныхРеквизитов(НачальныйНомер, КонечныйНомер, Видимость)
	Для Сч = НачальныйНомер По КонечныйНомер Цикл
		Элементы["ДеревоПомеченныхНаУдалениеРеквизит" + Сч].Видимость = Видимость;
	КонецЦикла;
КонецПроцедуры

&НаСервере
Процедура ДобавитьДополнительныеРеквизиты(НачальныйНомер, ЧислоДобавляемыхРеквизитов)
	ДобавляемыеРеквизиты = Новый Массив;
	ПоследняяЦифраВИмениРеквизита = НачальныйНомер+ЧислоДобавляемыхРеквизитов-1;
	Для Сч = НачальныйНомер По ПоследняяЦифраВИмениРеквизита Цикл
		ДобавляемыеРеквизиты.Добавить(Новый РеквизитФормы("Реквизит"+Сч, Новый ОписаниеТипов(), "ДеревоПомеченныхНаУдаление"));
	КонецЦикла;
	ИзменитьРеквизиты(ДобавляемыеРеквизиты);
	
	Для Сч = НачальныйНомер По ПоследняяЦифраВИмениРеквизита Цикл
		ЭлементФормы = Элементы.Добавить("ДеревоПомеченныхНаУдалениеРеквизит"+Сч, Тип("ПолеФормы"), Элементы.ДеревоПомеченныхНаУдаление);
		ЭлементФормы.Вид = ВидПоляФормы.ПолеВвода;
		ЭлементФормы.ПутьКДанным = "ДеревоПомеченныхНаУдаление.Реквизит"+Сч;
	КонецЦикла;
КонецПроцедуры

#КонецОбласти

#Область КомандыФормы

&НаКлиенте
Функция КоличествоВыбранныхОбъектов()
	Результат = Новый Структура;
	Результат.Вставить("КоличествоВыбранных", 0);
	Результат.Вставить("КоличествоВсего", 0);
	
	Для каждого СтрокаГруппы Из ДеревоПомеченныхНаУдаление.ПолучитьЭлементы() Цикл
		
		Для каждого СтрокаЭлемента Из СтрокаГруппы.ПолучитьЭлементы() Цикл
			Если СтрокаЭлемента.Пометка = 1 Тогда
				Результат.КоличествоВыбранных = Результат.КоличествоВыбранных + 1;
			КонецЕсли;
			Результат.КоличествоВсего = Результат.КоличествоВсего + 1;
		КонецЦикла;
		
	КонецЦикла;
	
	// При отборе метаданных всегда выбрано не все
	Если ОтборМетаданных.Количество() <> 0 Тогда
		Результат.КоличествоВсего = -1;
	КонецЕсли;
	
	Возврат Результат;
КонецФункции

&НаКлиенте
Процедура ЗарегистрироватьДействиеМестаИспользования(РедактируемоеМестоИспользования, Действие, Параметр = Неопределено)
	ДействиеПредставление = ?(Параметр = Неопределено,
								ДействияМестИспользованияНеудаленных.НайтиПоЗначению(Действие).Представление,
								ПредставлениеКомандыЗаменитьНа(РедактируемоеМестоИспользования, Параметр));

	Если Действие = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Успешно = Истина;
	
	Если Действие = "Удалить" Тогда
		Фильтр = Новый Структура("ОбнаруженныйСсылка",РедактируемоеМестоИспользования.ОбнаруженныйСсылка);
		ЗарегистрированноеДействие = ТаблицаДействий.НайтиСтроки(Фильтр);
		
		Если ЗарегистрированноеДействие.Количество() <> 0 Тогда
			Для каждого УдаляемоеДействие Из ЗарегистрированноеДействие Цикл
				ТаблицаДействий.Удалить(УдаляемоеДействие);
			КонецЦикла;
		КонецЕсли;
		
		ЗарегистрированноеДействие = ТаблицаДействий.Добавить();
		ЗарегистрированноеДействие.Действие = Действие;
		ЗарегистрированноеДействие.ОбнаруженныйСсылка = РедактируемоеМестоИспользования.ОбнаруженныйСсылка;
		ЗарегистрированноеДействие.ПараметрДействия = Параметр;
		ЗарегистрированноеДействие.Источник = РедактируемоеМестоИспользования.УдаляемыйСсылка;
	ИначеЕсли Действие = "ЗаменитьСсылку" Тогда
		Фильтр = Новый Структура("ОбнаруженныйСсылка",РедактируемоеМестоИспользования.ОбнаруженныйСсылка);
		ЗарегистрированноеДействие = ТаблицаДействий.НайтиСтроки(Фильтр);
		Для каждого УдаляемоеДействие Из ЗарегистрированноеДействие Цикл
			ТаблицаДействий.Удалить(УдаляемоеДействие);
		КонецЦикла;
		
		Фильтр = Новый Структура("Источник, Действие", РедактируемоеМестоИспользования.УдаляемыйСсылка, "ЗаменитьСсылку");
		ЗарегистрированноеДействие = ТаблицаДействий.НайтиСтроки(Фильтр);
		Для каждого ИзменяемоеДействие Из ЗарегистрированноеДействие Цикл
			ИзменяемоеДействие.ПараметрДействия = Параметр;
		КонецЦикла;
		
		Если ЗарегистрированноеДействие.Количество() = 0 Тогда
			ИзменяемоеДействие = ТаблицаДействий.Добавить();
			ИзменяемоеДействие.Действие = Действие;
			ИзменяемоеДействие.ОбнаруженныйСсылка = РедактируемоеМестоИспользования.ОбнаруженныйСсылка;
			ИзменяемоеДействие.ПараметрДействия = Параметр;
			ИзменяемоеДействие.Источник = РедактируемоеМестоИспользования.УдаляемыйСсылка;
		КонецЕсли;
		
		// Замена ссылки действует на все места использования, кроме удаляемых.
		Для каждого МестоИспользования Из МестаИспользованияНеудаленных.ПолучитьЭлементы() Цикл
			Фильтр = Новый Структура("ОбнаруженныйСсылка", МестоИспользования.ОбнаруженныйСсылка);
			ТекущееДействие = ТаблицаДействий.НайтиСтроки(Фильтр);
			
			Если ТекущееДействие.Количество() = 0 Тогда
				ИзменяемоеДействие = ТаблицаДействий.Добавить();
				ИзменяемоеДействие.Действие = Действие;
				ИзменяемоеДействие.ОбнаруженныйСсылка = МестоИспользования.ОбнаруженныйСсылка;
				ИзменяемоеДействие.ПараметрДействия = Параметр;
				ИзменяемоеДействие.Источник = МестоИспользования.УдаляемыйСсылка;
			КонецЕсли;
		КонецЦикла;
	Иначе
		СообщениеПользователю = НСтр("ru='Для места использования %1 нельзя выбрать действие %2.'");
		СообщениеПользователю = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СообщениеПользователю, 
		РедактируемоеМестоИспользования.ОбнаруженныйСсылка,
		РедактируемоеМестоИспользования.ДействиеПредставление);
		Состояние(СообщениеПользователю);
		Успешно = Ложь;
	КонецЕсли;
	
	Если Успешно Тогда
		
		РедактируемоеМестоИспользования.Действие = Действие;
		РедактируемоеМестоИспользования.ДействиеПредставление = ДействиеПредставление;
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПриПодтвержденииУдалить(Результат, ДополнительныеПараметры) Экспорт
	Если Результат <> КодВозвратаДиалога.Да Тогда
		Возврат;
	КонецЕсли;
	ПараметрДействия = ?(ДополнительныеПараметры.КоличествоВсего = ДополнительныеПараметры.КоличествоВыбранных,
		"ПолноеУдаление", "");
	ДобавитьЗадание(ЗаданияФормы().УдалениеПомеченных, ПараметрДействия);
	ЗапуститьЗадание();
КонецПроцедуры

&НаКлиенте
Процедура ОткрытьФормуЗавершенияРаботыПользователей()
	
	Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.ЗавершениеРаботыПользователей") Тогда
		Оповещение = Новый ОписаниеОповещения("ПослеУстановкиМонопольногоРежима", ЭтотОбъект);
		ПараметрыФормы = Новый Структура("УдалениеПомеченныхОбъектов", Истина);
		МодульСоединенияИБКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СоединенияИБКлиент");
		МодульСоединенияИБКлиент.ПриОткрытииФормыОшибкиУстановкиМонопольногоРежима(Оповещение, ПараметрыФормы);
	Иначе
		СтандартныеПодсистемыКлиент.ОткрытьСписокАктивныхПользователей();
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ПослеУстановкиМонопольногоРежима(Результат, ДополнительныеПараметры) Экспорт
	Если Результат = Ложь Тогда // Монопольный режим установлен.
		ДобавитьЗадание(ЗаданияФормы().УдалениеПомеченных);
		ЗапуститьЗадание();
	КонецЕсли;
КонецПроцедуры

#КонецОбласти

#Область СобытияФормы

&НаСервереБезКонтекста
Функция ОтборМетаданныхТолькоСуществующие(ОтборМетаданных)
	Результат = Новый СписокЗначений;
	
	Для каждого ВыбранныеМетаданные Из ОтборМетаданных Цикл
		Если ОбщегоНазначения.ОбъектМетаданныхПоПолномуИмени(ВыбранныеМетаданные.Значение) = Неопределено Тогда
			Продолжить;
		КонецЕсли;     
		
		Результат.Добавить(ВыбранныеМетаданные.Значение, ВыбранныеМетаданные.Представление);
	КонецЦикла;                     
	
	Возврат Результат;
КонецФункции

&НаСервере
Процедура УстановитьПереданныйОтборМетаданных()
	Перем Элемент;
	Перем УстановленныйОтбор;
	УстановленныйОтбор = Новый СписокЗначений;
	Для Каждого Элемент Из Параметры.ОтборМетаданных Цикл
		УстановленныйОтбор.Добавить(Элемент.Значение, ОбщегоНазначения.ОбъектМетаданныхПоПолномуИмени(Элемент.Значение).Представление());
	КонецЦикла;
	УстановитьОтборМетаданных(ЭтотОбъект, УстановленныйОтбор);
	Параметры.ОтборМетаданных = УстановленныйОтбор;
КонецПроцедуры

// Настройка формы, если форма открыта через клиентский АПИ.
&НаСервере
Процедура НастроитьФормуДляРаботыКакСервис()
	УдалятьПриОткрытии = Истина;
	Элементы.СтраницыИнформация.Видимость = Ложь;
	Элементы.ДеревоПомеченныхНаУдалениеНастроить.Видимость = Ложь;
	Элементы.Назад.Видимость = Ложь;
	Элементы.ГруппаНастройкиОтбораПоиска.Видимость = Ложь;
	Элементы.КоманднаяПанельФормы.Видимость = Ложь;
	Элементы.СтраницыОтображениеСостояния.Видимость = Истина;
	АвтоЗаголовок = Ложь;
	Заголовок = "";
КонецПроцедуры

&НаСервере
Процедура УстановитьУсловноеОформление()
	ЦветГиперссылка = Метаданные.ЭлементыСтиля.ГиперссылкаЦвет.Значение;
	ЦветНеактивнойНадписи = Метаданные.ЭлементыСтиля.ТекстЗапрещеннойЯчейкиЦвет.Значение;
	
	ЭлементыУсловногоОформления = УсловноеОформление.Элементы;
	ЭлементыУсловногоОформления.Очистить();

	ЭлементОформления = ЭлементыУсловногоОформления.Добавить();

	ГруппаИ = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	ГруппаИ.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ;
	ОтборОформления = ГруппаИ.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборОформления.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("МестаИспользованияНеудаленных.Действие");
	ОтборОформления.ВидСравнения = ВидСравненияКомпоновкиДанных.НеЗаполнено;

	ОтборОформления = ГруппаИ.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборОформления.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("МестаИспользованияНеудаленных.ОсновнаяПричина");
	ОтборОформления.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
	ОтборОформления.ПравоеЗначение = Истина;
	
	ЭлементОформления.Оформление.УстановитьЗначениеПараметра("Текст", НСтр("ru='Выберите действие'"));
	ЭлементОформления.Оформление.УстановитьЗначениеПараметра("Шрифт", Метаданные.ЭлементыСтиля.ДействиеВКолонкеСпискаШрифт.Значение);

	ПолеОформления = ЭлементОформления.Поля.Элементы.Добавить();
	ПолеОформления.Поле = Новый ПолеКомпоновкиДанных("СвязиНеУдаленныхДействие");
	
	// Цвет гиперссылки
	ЭлементОформления = ЭлементыУсловногоОформления.Добавить();
	ОтборОформления = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборОформления.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("МестаИспользованияНеудаленных.ОсновнаяПричина");
	ОтборОформления.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
	ОтборОформления.ПравоеЗначение = Истина;
	
	ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветГиперссылка);
	
	ПолеОформления = ЭлементОформления.Поля.Элементы.Добавить();
	ПолеОформления.Поле = Новый ПолеКомпоновкиДанных("СвязиНеУдаленныхДействие");
	
	// Заголовки колонок
	УстановитьУсловноеОформлениеДополнительныхРеквизитов(ЭлементыУсловногоОформления, ЦветНеактивнойНадписи);
	
	// Доступность выбора действий
	ЭлементОформления = ЭлементыУсловногоОформления.Добавить();
	ОтборОформления = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборОформления.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("МестаИспользованияНеудаленных.ОсновнаяПричина");
	ОтборОформления.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
	ОтборОформления.ПравоеЗначение = Ложь;
	
	ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ТолькоПросмотр", Истина);
	
	ПолеОформления = ЭлементОформления.Поля.Элементы.Добавить();
	ПолеОформления.Поле = Новый ПолеКомпоновкиДанных("СвязиНеУдаленныхДействие");
КонецПроцедуры

&НаСервере
Процедура УстановитьУсловноеОформлениеДополнительныхРеквизитов(ЭлементыУсловногоОформления, ЦветНеактивнойНадписи)
	ЭлементОформления = ЭлементыУсловногоОформления.Добавить();
	
	ОтборОформления = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборОформления.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ДеревоПомеченныхНаУдаление.ЭтоОписаниеОбъектаМетаданных");
	ОтборОформления.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
	ОтборОформления.ПравоеЗначение = Истина;
	
	ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветНеактивнойНадписи);
	
	ЧислоДополнительныхРеквизитов = УдалениеПомеченныхОбъектовСлужебный.ЧислоДополнительныхРеквизитов(
		ДополнительныеРеквизитыПомеченныхНаУдаления.Выгрузить());
	
	Для Сч = 1 По ЧислоДополнительныхРеквизитов Цикл
		ПолеОформления = ЭлементОформления.Поля.Элементы.Добавить();
		ПолеОформления.Поле = Новый ПолеКомпоновкиДанных("ДеревоПомеченныхНаУдалениеРеквизит" + Сч);
	КонецЦикла;
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура УстановитьСписокДействийМестИспользования(Форма)
	Форма.ДействияМестИспользованияНеудаленных.Очистить();
	Форма.ДействияМестИспользованияНеудаленных.Добавить("Удалить", НСтр("ru='Удалить'"));
	Форма.ДействияМестИспользованияНеудаленных.Добавить("ЗаменитьСсылку", НСтр("ru='Заменить %ПредставлениеСсылка% на'"));
	
	Форма.Элементы.СвязиНеУдаленныхДействие.СписокВыбора.Очистить();
	Для Каждого ЭлементСписка Из Форма.ДействияМестИспользованияНеудаленных Цикл
		Форма.Элементы.СвязиНеУдаленныхДействие.СписокВыбора.Добавить(ЭлементСписка.Значение, ЭлементСписка.Представление);
	КонецЦикла;
КонецПроцедуры

#КонецОбласти

#Область ПриАктивизацииСтрокиНеУдаленных

&НаКлиенте
Процедура ПоказатьСвязиНеУдаленныхНаКлиенте()
	Если НеУдаленныеИдентификаторТекущейСтроки = Элементы.НеУдаленные.ТекущаяСтрока Тогда
		Возврат;
	КонецЕсли;

	ПодробныйТекстОшибки = "";
	ЗаполнитьМестаИспользованияНеудаленныхОбъектов(ЭтотОбъект);
	
	Если МестаИспользованияНеудаленных.ПолучитьЭлементы().Количество() = 0 Тогда
		Элементы.СтраницыВариантовОтображенияПричин.ТекущаяСтраница = Элементы.СтраницаТекстОшибки;
		УстановитьТекстОшибки();
		Элементы.Действия.Доступность = Ложь;
	Иначе	
		Элементы.СтраницыВариантовОтображенияПричин.ТекущаяСтраница = Элементы.СтраницаПричиныНеУдаления;
		СтандартныеПодсистемыКлиент.РазвернутьУзлыДерева(ЭтотОбъект, "МестаИспользованияНеудаленных", "*", Истина);
		Элементы.Действия.Доступность = Истина;
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура УстановитьТекстОшибки()
	Элементы.ТекстОшибки.Заголовок = ТекстОшибки;
	Элементы.СсылкаПодробнее.Видимость = ЗначениеЗаполнено(ПодробныйТекстОшибки) ;
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура ЗаполнитьМестаИспользованияНеудаленныхОбъектов(Форма)
	НеУдаленныеИдентификаторТекущейСтроки = Форма.Элементы.НеУдаленные.ТекущаяСтрока;
	Если НеУдаленныеИдентификаторТекущейСтроки = Неопределено Тогда
		СтрокаДерева = Неопределено;
	Иначе
		СтрокаДерева = Форма.НеУдаленные.НайтиПоИдентификатору(НеУдаленныеИдентификаторТекущейСтроки);
	КонецЕсли;
	
	ОтображаемыеСтроки = Форма.МестаИспользованияНеудаленных.ПолучитьЭлементы();
	ОтображаемыеСтроки.Очистить();
	Форма.КешПричинНеудаления.Очистить();
	
	Если СтрокаДерева = Неопределено Или СтрокаДерева.НомерКартинки < 1 Тогда
		// Ничего не выбрано или выбрана группа.
		Форма.ТекстОшибки = НСтр("ru = 'Выберите объект, чтобы узнать причину,
			|по которой его не удалось удалить.'")
	Иначе
		// Выбрана ссылка не удаленного объекта.
		Показываемые = Форма.СвязиНеудаленных.НайтиСтроки(Новый Структура("УдаляемыйСсылка", СтрокаДерева.УдаляемыйСсылка));
		Для Каждого СтрокаТаблицы Из Показываемые Цикл
			Если СтрокаТаблицы.ЭтоОшибка Тогда
				Форма.ТекстОшибки = СтрокаТаблицы.ОбнаруженныйСсылка;
				Форма.ПодробныйТекстОшибки = СтрокаТаблицы.Представление;
				Прервать;
			КонецЕсли;
				
			ДобавитьПричиныНеудаленияРекурсивно(Форма, ОтображаемыеСтроки, СтрокаТаблицы);
			Форма.КешПричинНеудаления.Добавить(СтрокаТаблицы.УдаляемыйСсылка);
		КонецЦикла;
	КонецЕсли;
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура ЗаполнитьДействиеВСтрокеМестаИспользованияНеудаленных(Форма, Знач ПричинаНеудаления, Действие = "")
	Если ПричинаНеудаления.ЭтоОшибка Тогда
		Возврат;
	КонецЕсли;
	
	ТаблицаДействий = Форма.ТаблицаДействий;
	Фильтр = Новый Структура("ОбнаруженныйСсылка, Действие", 
					ПричинаНеудаления.ОбнаруженныйСсылка, "Удалить");
	ВыбранныеДействия = ТаблицаДействий.НайтиСтроки(Фильтр);
	
	Если ВыбранныеДействия.Количество() = 0 Тогда
		Фильтр = Новый Структура("Источник, Действие", 
						ПричинаНеудаления.УдаляемыйСсылка, "ЗаменитьСсылку");
		ВыбранныеДействия = ТаблицаДействий.НайтиСтроки(Фильтр);
	КонецЕсли;
	
	Если ВыбранныеДействия.Количество() > 0 Тогда
		Действие = ВыбранныеДействия[0].Действие;
		ПараметрДействия = ВыбранныеДействия[0].ПараметрДействия;
	КонецЕсли;	
	
	Если НЕ ПричинаНеудаления.ОсновнаяПричина Тогда
		Действие = "Удалить";
	КонецЕсли;
	
	ПричинаНеудаления.Действие = Действие;
			
	Если Действие = "ЗаменитьСсылку" Тогда
		ПричинаНеудаления.ДействиеПредставление = ПредставлениеКомандыЗаменитьНа(ПричинаНеудаления, ПараметрДействия);
	ИначеЕсли Действие = "Удалить" Тогда
		ПричинаНеудаления.ДействиеПредставление = Форма.ДействияМестИспользованияНеудаленных.НайтиПоЗначению(Действие).Представление;
	Иначе
		ПричинаНеудаления.ДействиеПредставление = "";
	КонецЕсли;
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура ДобавитьПричиныНеудаленияРекурсивно(Форма, КоллекцияСтрокРодителя, ДанныеСтроки)
	КешПричинНеудаления = Форма.КешПричинНеудаления;

	НоваяСтрока = КоллекцияСтрокРодителя.Добавить();
	ПодчиненныеСтроки = НоваяСтрока.ПолучитьЭлементы();
	Если ДанныеСтроки.ЭтоОшибка Тогда
		ЗаполнитьЗначенияСвойств(НоваяСтрока, ДанныеСтроки,"ЭтоОшибка,НомерКартинки");
		НоваяСтрока.Представление = ДанныеСтроки.ОбнаруженныйСсылка;
		НоваяСтрока.ОбнаруженныйСсылка = ?(ЗначениеЗаполнено(ДанныеСтроки.Представление), ДанныеСтроки.Представление, ДанныеСтроки.ОбнаруженныйСсылка);
	Иначе	
		ЗаполнитьЗначенияСвойств(НоваяСтрока, ДанныеСтроки);
	КонецЕсли;
	Показываемые = Форма.СвязиНеудаленных.НайтиСтроки(Новый Структура("УдаляемыйСсылка", ДанныеСтроки.ОбнаруженныйСсылка));
	
	СодержатьсяТолькоОшибки = Истина;
	Для Каждого СтрокаТаблицы Из Показываемые Цикл
		Если НЕ СтрокаТаблицы.ЭтоОшибка Тогда
			СодержатьсяТолькоОшибки = Ложь;
		КонецЕсли;
		
		Если КешПричинНеудаления.НайтиПоЗначению(СтрокаТаблицы.ОбнаруженныйСсылка) = Неопределено Тогда
			КешПричинНеудаления.Добавить(СтрокаТаблицы.УдаляемыйСсылка);
			ДобавитьПричиныНеудаленияРекурсивно(Форма, ПодчиненныеСтроки, СтрокаТаблицы);
		КонецЕсли;
	КонецЦикла;

	НоваяСтрока.ОсновнаяПричина = НЕ НоваяСтрока.ЭтоОшибка
								И (ПодчиненныеСтроки.Количество() = 0 
									ИЛИ СодержатьсяТолькоОшибки
									ИЛИ Показываемые.Количество() = 0);
									
	ЗаполнитьДействиеВСтрокеМестаИспользованияНеудаленных(Форма,
		 НоваяСтрока,
		 ?(Показываемые.Количество() <> 0, "Удалить", ""));

КонецПроцедуры

#КонецОбласти

#Область ПриАктивизацииСтрокиМестИспользованияНеудаленных

&НаКлиенте
Процедура МестаИспользованияНеудаленныхПриАктивизацииСтроки(Элемент)
	ТекущиеДанные = Элементы.МестаИспользованияНеудаленных.ТекущиеДанные;

	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;

	Если ЗначениеЗаполнено(ТекущиеДанные.ОбнаруженныйСсылка) Тогда
		Элементы.СвязиНеУдаленныхДействие.СписокВыбора.Очистить();
		
		// Дл ошибок и для констант не доступно действие Удаление
		Если ТипЗнч(ТекущиеДанные.ОбнаруженныйСсылка) <> Тип("Строка") Тогда
			Элементы.СвязиНеУдаленныхДействие.СписокВыбора.Добавить("Удалить", ПредставлениеКомандыУдалить(ТекущиеДанные));
		КонецЕсли;
		
		Действия = ТаблицаДействий.НайтиСтроки(Новый Структура("ОбнаруженныйСсылка", ТекущиеДанные.ОбнаруженныйСсылка));
		Если НЕ(Действия.Количество() > 0 
				И Действия[0].Действие = "Удалить" 
				И Действия[0].Источник <> ТекущиеДанные.УдаляемыйСсылка) Тогда
		
			Элементы.СвязиНеУдаленныхДействие.СписокВыбора.Добавить("ЗаменитьСсылку", ПредставлениеКомандыЗаменитьНа(ТекущиеДанные));
		КонецЕсли;

	КонецЕсли;
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Функция ПредставлениеКомандыЗаменитьНа(ТекущиеДанные, Параметр = Неопределено)
	СтрокаВерхнегоУровня = ТекущиеДанные.ПолучитьРодителя();
	
	Если СтрокаВерхнегоУровня = Неопределено Тогда
		ПредставлениеСтрокиВерхнегоУровня = ТекущиеДанные.ПредставлениеУдаляемый;
	Иначе	
		ПредставлениеСтрокиВерхнегоУровня = СтрокаВерхнегоУровня.Представление;
	КонецЕсли;
	
	ПредставлениеКомандыЗаменитьНа = СтрЗаменить(НСтр("ru='Заменить %ПредставлениеСсылка% на'"),
										"%ПредставлениеСсылка%", ПредставлениеСтрокиВерхнегоУровня)
										+ Символы.НПП + ?(Параметр = Неопределено, "", Параметр);
		
	Возврат ПредставлениеКомандыЗаменитьНа;
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ПредставлениеКомандыУдалить(ТекущиеДанные)
	Представление = НСтр("ru='Удалить'") + Символы.НПП + ТекущиеДанные.Представление;
	Возврат Представление;
КонецФункции

#КонецОбласти

&НаКлиенте
Процедура ПоказатьОбъектТаблицы(ТаблицаЭлемент)
	СтрокаТаблицы = ТаблицаЭлемент.ТекущиеДанные;
	Если СтрокаТаблицы = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Значение = Неопределено;
	Если Не СтрокаТаблицы.Свойство("ОбнаруженныйСсылка", Значение)
		И Не СтрокаТаблицы.Свойство("УдаляемыйСсылка", Значение) Тогда
		Возврат;
	КонецЕсли;
	
	Если ТипЗнч(Значение) = Тип("Строка") 
		И НЕ ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СтрокаТаблицы, "ЭтоОшибка", Ложь) Тогда
			
		Если СтрокаТаблицы.Свойство("ЭтоКонстанта") И СтрокаТаблицы.ЭтоКонстанта Тогда
			ПутьКФорме = Значение + ".ФормаКонстант";
		Иначе
			ПутьКФорме = Значение + ".ФормаСписка";
		КонецЕсли;
		ОткрытьФорму(ПутьКФорме);
	ИначеЕсли ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СтрокаТаблицы, "ЭтоОшибка", Ложь) Тогда
		СтандартныеПодсистемыКлиент.ПоказатьПодробнуюИнформацию(Неопределено, СтрокаТаблицы.ОбнаруженныйСсылка);
	Иначе
		ПоказатьЗначение(, Значение);
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ДеревоПомеченныхНаУдалениеУстановитьПометкуВСписке(Данные, Пометка, ПроверятьРодителя)
	
	// Устанавливаем подчиненным
	ЭлементыСтроки = Данные.ПолучитьЭлементы();
	
	Для Каждого Элемент Из ЭлементыСтроки Цикл
		Элемент.Пометка = Пометка;
		ДеревоПомеченныхНаУдалениеУстановитьПометкуВСписке(Элемент, Пометка, Ложь);
	КонецЦикла;
	
	// Проверяем родителя
	Родитель = Данные.ПолучитьРодителя();
	
	Если ПроверятьРодителя И Родитель <> Неопределено Тогда 
		ДеревоПомеченныхНаУдалениеПроверитьРодителя(Родитель);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ДеревоПомеченныхНаУдалениеПроверитьРодителя(Родитель)
	
	ЭлементыСтроки = Родитель.ПолучитьЭлементы();
	Родитель.Пометка = ЗначениеПометкиЭлементов(ЭлементыСтроки);
	
КонецПроцедуры

// Параметры:
//   Результат - СписокЗначений из Строка
//   ДополнительныеПараметры - Структура
//
&НаКлиенте
Процедура НастроитьОтборЗавершение(Результат, ДополнительныеПараметры) Экспорт
	Если Результат = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	ТекущийОтбор = ОбщегоНазначенияКлиент.СкопироватьРекурсивно(ОтборМетаданных);
	УстановитьОтборМетаданных(ЭтотОбъект, Результат);
	
	Если ОтборМетаданныхИзменен(ТекущийОтбор, Результат) Тогда
		ЗапуститьЗадание(ЗаданияФормы().ПоискПомеченных);
	КонецЕсли;
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура УстановитьОтборМетаданных(Форма, Результат)
	Форма.ОтборМетаданных = ?(Результат = Неопределено, Новый СписокЗначений, Результат.Скопировать());// СписокЗначений из Строка
	Форма.Элементы.НастроитьОтбор.Заголовок = ПредставлениеОтбораМетаданных(Результат);
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Функция ПредставлениеОтбораМетаданных(ЗначениеОтбора)
	ПредставлениеОтбора = "";
	Представление = Новый Массив;
	Для Каждого Отбор Из ЗначениеОтбора Цикл
		Представление.Добавить(Отбор.Представление);
	КонецЦикла;
	ПредставлениеОтбора = СтрСоединить(Представление, ", ");
	Возврат ?(ПустаяСтрока(ПредставлениеОтбора), НСтр("ru='Все помеченные на удаление'"), ПредставлениеОтбора);
КонецФункции

&НаКлиенте
Функция ОтборМетаданныхИзменен(СтарыйОтбор, Результат)
	ТребуетсяПовторныйПоиск = Ложь;
	Для Каждого Элемент Из Результат Цикл
		Если ОтборМетаданных.НайтиПоЗначению(Элемент.Значение) = Неопределено Тогда
			ТребуетсяПовторныйПоиск = Истина;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	
	Если СтарыйОтбор.Количество() <> Результат.Количество() Тогда
		ТребуетсяПовторныйПоиск = Истина;
	КонецЕсли;
	
	Возврат ТребуетсяПовторныйПоиск;
КонецФункции

#Область ФоновыеЗадания

#Область ПоискПомеченныхНаУдаление

&НаКлиенте
Процедура НачатьПоискПомеченных(Параметр = Неопределено)
	УстановитьСостояниеВыбораПомеченныхНаУдалениеСПанельюСостояния();
	
	ПредставлениеОперации = НСтр("ru='Поиск помеченных на удаление'");
	НачатьПоискПомеченных_НастройкаФормы(ЭтотОбъект);

	
	Обработчик = Новый ОписаниеОповещения("ПослеЗавершенияПоискаПомеченных", ЭтотОбъект);
	
	ВыполняемаяОперация = НачатьПоискПомеченныхСервер(ОтборМетаданных, УникальныйИдентификатор);
	ПриНачалеФоновогоЗадания(Обработчик);
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура НачатьПоискПомеченных_НастройкаФормы(Форма)
	
	Форма.Элементы.СтраницыОтображениеСостояния.ТекущаяСтраница = Форма.Элементы.СостояниеВыполняется;
	Форма.Элементы.ДекорацияПредставлениеДлительнойОперации.Заголовок = НСтр("ru='Выполняется поиск помеченных на удаление...'");
	Форма.Элементы.СтраницыИнформация.ТолькоПросмотр = Истина;
	Форма.Элементы.ГруппаАктивныПослеПоискаПомеченные.Доступность = Ложь;

КонецПроцедуры

&НаКлиенте
Процедура ПриНачалеФоновогоЗадания(Знач Обработчик, ЭтоПроцессУдаления = Ложь)
	Перем НастройкиОжидания;
	НастройкиОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
	НастройкиОжидания.ВыводитьОкноОжидания = Ложь;
	НастройкиОжидания.ВыводитьПрогрессВыполнения = Истина;
	ДополнительныеПараметры = Новый Структура;
	ДополнительныеПараметры.Вставить("ЭтоПроцессУдаления", ЭтоПроцессУдаления);
	НастройкиОжидания.ОповещениеОПрогрессеВыполнения = Новый ОписаниеОповещения("ПриОбновленииПрогрессаФоновогоЗадания",
		ЭтотОбъект, ДополнительныеПараметры);
	ДлительныеОперацииКлиент.ОжидатьЗавершение(ВыполняемаяОперация, Обработчик, НастройкиОжидания);
	Если ВыполняемаяОперация <> Неопределено И ВыполняемаяОперация.Статус = "Выполняется" Тогда
		ПоказатьДиалогПередЗакрытием = Истина;
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПослеЗавершенияФоновогоЗадания(Результат)
	РезультатПредыдущегоШага = Результат;
	ПоказатьДиалогПередЗакрытием = Ложь;
	ВыполняемаяОперация = Неопределено;
	ПараметрЗадания = УдалитьТекущееЗадание();	
	ВыполняетсяЗадание = Ложь;
	
	Если КоличествоЗаданийВОчереди() = 0 Тогда
		УстановитьМонопольныйРежимНаСервере(Ложь);
	КонецЕсли;
	
	Если Результат.Статус <> "Ошибка" Тогда
		ЗапуститьЗадание(,ПараметрЗадания);
	КонецЕсли;
КонецПроцедуры

&НаСервере
Функция НачатьПоискПомеченныхСервер(ОтборМетаданных, УникальныйИдентификаторФормы)
	ИмяМетода = "УдалениеПомеченныхОбъектовСлужебный.ПомеченныеНаУдаление";
	
	ПараметрыМетода = ДлительныеОперации.ПараметрыВыполненияФункции(УникальныйИдентификаторФормы);
	ПараметрыМетода.НаименованиеФоновогоЗадания = НСтр("ru = 'Поиск помеченных на удаление'");
	Задание = ДлительныеОперации.ВыполнитьФункцию(ПараметрыМетода, ИмяМетода,
		ОтборМетаданных, 
		ДополнительныеРеквизитыПомеченныхНаУдаления.Выгрузить(), 
		РеквизитФормыВЗначение("ДеревоПомеченныхНаУдаление"));

	Возврат Задание;
КонецФункции

&НаКлиенте
Процедура ПослеЗавершенияПоискаПомеченных(Результат, ДополнительныеПараметры) Экспорт
	Если Результат = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	ВыполняетсяЗадание = Ложь;
	
	Если Результат.Статус = "Ошибка" Тогда
		
		ЗаполнитьИнформациюОшибкамиФоновогоЗадания(ЭтотОбъект, Результат);
		УстановитьСостояниеВыбораПомеченныхНаУдалениеСПанельюСостояния();
		
	Иначе
		
		ЗаполнитьДеревоПомеченныхНаУдаление(Результат);
	
		Если ДеревоПомеченныхНаУдаление.ПолучитьЭлементы().Количество() = 0 Тогда
			Элементы.СтраницыОтображениеСостояния.ТекущаяСтраница = Элементы.СостояниеУдалениеНеТребуется;
			ВыполняетсяЗадание = Истина;
			УстановитьСостояниеВыбораПомеченныхНаУдалениеСПанельюСостояния();
			ОчиститьОчередьЗаданийФормы();
		Иначе
			УстановитьСостояниеВыбораПомеченныхНаУдаление();
		КонецЕсли;
		
	КонецЕсли;
	
	ПослеЗавершенияФоновогоЗадания(Результат);
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура ЗаполнитьИнформациюОшибкамиФоновогоЗадания(Форма, Результат)
	Форма.ПодробныйТекстОшибкиФоновогоЗадания = Результат.ПодробноеПредставлениеОшибки;
	Форма.Элементы.ДекорацияПредставлениеЗавершенияНеУспешно.Заголовок = 
		?(ЭтоОшибкаУстановкиМонопольногоРежима(Результат.КраткоеПредставлениеОшибки),
			НСтр("ru='Не удалось установить монопольный режим'"),
			Результат.КраткоеПредставлениеОшибки);
	Форма.Элементы.СтраницыОтображениеСостояния.ТекущаяСтраница = Форма.Элементы.СостояниеВыполненоСОшибками;
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьДеревоПомеченныхНаУдаление(Результат)
	ДеревоЗначений = ПолучитьИзВременногоХранилища(Результат.АдресРезультата);
	УдалитьИзВременногоХранилища(Результат.АдресРезультата);
	ЗаполнитьКоллекциюЭлементовДереваДанныхФормы(ДеревоПомеченныхНаУдаление, ДеревоЗначений);
	УдалитьИзВременногоХранилища(Результат.АдресРезультата);
КонецПроцедуры

#КонецОбласти

#Область УдалениеПомеченных

&НаКлиенте
Процедура НачатьУдалениеПомеченных(Параметр = Неопределено)
	ПредставлениеОперации = НСтр("ru='Удаление помеченных'");
	Элементы.СтраницыОтображениеСостояния.ТекущаяСтраница = Элементы.СостояниеВыполняется;
	Элементы.ДекорацияПредставлениеДлительнойОперации.Заголовок = НСтр("ru='Выполняется удаление помеченных...'");
	УстановитьСостояниеВыбораПомеченныхНаУдалениеСПанельюСостояния();
	
	Элементы.КоманднаяПанельФормы.Доступность = Ложь;
	Элементы.СтраницыИнформация.ТолькоПросмотр = Истина;

	Обработчик = Новый ОписаниеОповещения("ПослеЗавершенияУдаленияПомеченных", ЭтотОбъект);
	ВыполняемаяОперация = НачатьУдалениеПомеченныхСервер(
							УникальныйИдентификатор,
							РезультатПредыдущегоШага,
							Параметр = "ПолноеУдаление");
	ПриНачалеФоновогоЗадания(Обработчик);
КонецПроцедуры

&НаСервере
Функция УстановитьМонопольныйРежимНаСервере(МонопольныйРежим)
	Результат = Новый Структура;
	Результат.Вставить("Успешно", Истина);
	Результат.Вставить("ПодробноеПредставлениеОшибки", "");
	Результат.Вставить("КраткоеПредставлениеОшибки", "");
	Если МонопольныйРежим() <> МонопольныйРежим Тогда
		Попытка
			УстановитьМонопольныйРежим(МонопольныйРежим);
		Исключение
			ИнформацияОбОшибке = ИнформацияОбОшибке();
			Результат.Успешно = Ложь;
			Результат.КраткоеПредставлениеОшибки =  ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке);
			Результат.ПодробноеПредставлениеОшибки =  ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
			ИнформацияОбОшибке = ИнформацияОбОшибке();
			ЗаписьЖурналаРегистрации(НСтр("ru = 'Удаление помеченных'", ОбщегоНазначения.КодОсновногоЯзыка()),
				УровеньЖурналаРегистрации.Ошибка,
				,
				,
				Результат.КраткоеПредставлениеОшибки
				+ Символы.ПС + Символы.ПС 
				+ Результат.ПодробноеПредставлениеОшибки);
		КонецПопытки;
	КонецЕсли;
	
	Если НЕ МонопольныйРежим Тогда
		Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ЗавершениеРаботыПользователей") Тогда
			МодульСоединенияИБ = ОбщегоНазначения.ОбщийМодуль("СоединенияИБ");
			МодульСоединенияИБ.РазрешитьРаботуПользователей();
		КонецЕсли;
	КонецЕсли;
			
	Возврат Результат;
КонецФункции

&НаСервере
Функция НачатьУдалениеПомеченныхСервер(УникальныйИдентификаторФормы, РезультатПредыдущегоШага, ПовторныйПоиск = Ложь)
	Если УдалятьПриОткрытии Тогда
		ИсточникУдаляемыхОбъектов = Параметры.УдаляемыеОбъекты;
	ИначеЕсли ПовторныйПоиск Тогда
		ИсточникУдаляемыхОбъектов = Неопределено;
	Иначе	
		ИсточникУдаляемыхОбъектов = РеквизитФормыВЗначение("ДеревоПомеченныхНаУдаление");
	КонецЕсли;
	
	НастройкиДополнительныхРеквизитов = РеквизитФормыВЗначение("ДополнительныеРеквизитыПомеченныхНаУдаления");
	ИмяМетода = "УдалениеПомеченныхОбъектовСлужебный.УдалитьПомеченныеОбъекты";
	
	ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияФункции(УникальныйИдентификаторФормы);
	ПараметрыВыполнения.НаименованиеФоновогоЗадания = НСтр("ru = 'Удаление помеченных объектов'");
	
	ЗначениеРезультатаПредыдущегоШага = ?(РезультатПредыдущегоШага <> Неопределено 
			И ЭтоАдресВременногоХранилища(РезультатПредыдущегоШага.АдресРезультата),
		ПолучитьИзВременногоХранилища(РезультатПредыдущегоШага.АдресРезультата),
		Неопределено);
	
	ДопустимыеРежимыУдаления = УдалениеПомеченныхОбъектовСлужебный.ДопустимыеРежимыУдаления();
	ИтоговыйРежимУдаления = ?(ДопустимыеРежимыУдаления.Найти(РежимУдаления) <> Неопределено,
		РежимУдаления, "Стандартный");
	Если ИтоговыйРежимУдаления = "Монопольный" Тогда
		ДопустимыеРежимыУдаления = УдалениеПомеченныхОбъектовСлужебный.ДопустимыеРежимыУдаления();
		Задание = ДлительныеОперации.ВыполнитьФункцию(ПараметрыВыполнения, ИмяМетода,
			ИсточникУдаляемыхОбъектов,
			ИтоговыйРежимУдаления,
			НастройкиДополнительныхРеквизитов,
			ЗначениеРезультатаПредыдущегоШага,
			УникальныйИдентификаторФормы);
	Иначе
		ПараметрыУдаления = ПараметрыУдаленияПомеченныхОбъектов(ИсточникУдаляемыхОбъектов, ИтоговыйРежимУдаления,
			НастройкиДополнительныхРеквизитов, ЗначениеРезультатаПредыдущегоШага, УникальныйИдентификаторФормы);
		КоличествоПорций = ПараметрыУдаления.Количество();
		
		Задание = ДлительныеОперации.ВыполнитьФункциюВНесколькоПотоков(ИмяМетода,
			ПараметрыВыполнения, ПараметрыУдаления);
	КонецЕсли;
	
	Возврат Задание;
КонецФункции

&НаСервере
Функция ПараметрыУдаленияПомеченныхОбъектов(ИсточникУдаляемыхОбъектов, ИтоговыйРежимУдаления,
	НастройкиДополнительныхРеквизитов, ЗначениеРезультатаПредыдущегоШага, УникальныйИдентификаторФормы)
	
	Если ИсточникУдаляемыхОбъектов = Неопределено Тогда
		ИсточникУдаляемыхОбъектов = РеквизитФормыВЗначение("ДеревоПомеченныхНаУдаление");
	КонецЕсли;
	
	ПараметрыУдаления = Новый Соответствие;
	Если ТипЗнч(ИсточникУдаляемыхОбъектов) <> Тип("ДеревоЗначений") Тогда
		ПараметрыВызоваСервера = Новый Массив;
		ПараметрыВызоваСервера.Добавить(ИсточникУдаляемыхОбъектов);
		ПараметрыВызоваСервера.Добавить(ИтоговыйРежимУдаления);
		ПараметрыВызоваСервера.Добавить(НастройкиДополнительныхРеквизитов);
		ПараметрыВызоваСервера.Добавить(ЗначениеРезультатаПредыдущегоШага);
		ПараметрыВызоваСервера.Добавить(УникальныйИдентификаторФормы);
		ПараметрыУдаления.Вставить(0, ПараметрыВызоваСервера);
		Возврат ПараметрыУдаления;
	КонецЕсли;
	
	ИндексПорции = 0;
	
	ПараметрыВызоваСервера = Новый Массив;
	ПараметрыВызоваСервера.Добавить(ИсточникУдаляемыхОбъектов);
	ПараметрыВызоваСервера.Добавить(ИтоговыйРежимУдаления);
	ПараметрыВызоваСервера.Добавить(НастройкиДополнительныхРеквизитов);
	ПараметрыВызоваСервера.Добавить(ЗначениеРезультатаПредыдущегоШага);
	ПараметрыВызоваСервера.Добавить(УникальныйИдентификаторФормы);
	ПараметрыУдаления.Вставить(ИндексПорции, ПараметрыВызоваСервера);
	
	Возврат ПараметрыУдаления;
	
КонецФункции

&НаКлиенте
Процедура ПослеЗавершенияУдаленияПомеченных(Результат, ДополнительныеПараметры) Экспорт
	Если Результат = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	ВыполняетсяЗадание = Ложь;
	ПоказатьДиалогПередЗакрытием = Ложь;
	
	Если Результат.Статус = "Ошибка" Тогда
		СведенияОРезультатахУдаления = ОбработатьРезультатУдаленияОшибка(Результат);
	ИначеЕсли Результат.Статус = "Выполнено" Тогда 
		УникальныйИдентификаторСУчетомВладельца = ?(ВладелецФормы = Неопределено, УникальныйИдентификатор, ВладелецФормы.УникальныйИдентификатор);
		СведенияОРезультатахУдаления = ОбработатьРезультатУдаленияУспех(Результат, 
			УникальныйИдентификаторСУчетомВладельца, СведенияОРезультатахУдаления);
		ОбщегоНазначенияКлиент.ОповеститьОбИзмененииОбъектов(СведенияОРезультатахУдаления.Удаленные);
	КонецЕсли;
	
	ПослеЗавершенияФоновогоЗадания(Результат);
	
	Если УдалятьПриОткрытии И СведенияОРезультатахУдаления.Успешно Тогда
		Закрыть(СведенияОРезультатахУдаления);
	КонецЕсли;
КонецПроцедуры

&НаСервере
Функция ОбработатьРезультатУдаленияОшибка(Результат)
	УстановитьСостояниеВыбораПомеченныхНаУдалениеСПанельюСостояния();
	ЗаполнитьИнформациюОшибкамиФоновогоЗадания(ЭтотОбъект, Результат);
	УстановитьМонопольныйРежимНаСервере(Ложь);
	Возврат УдалениеПомеченныхОбъектовСлужебныйКлиентСервер.НовыйСведенияОРезультатахУдаления();
КонецФункции

&НаСервере
Функция ОбработатьРезультатУдаленияУспех(Результат, УникальныйИдентификаторФормы, СведенияОРезультатахУдаления)
	
	СведенияОРезультатахУдаления = ЗагрузитьРезультатУдаления(Результат, УникальныйИдентификаторФормы, 
		СведенияОРезультатахУдаления);
	Если СведенияОРезультатахУдаления.АдресРезультата <> "" Тогда 
		ОбработатьРезультатВыполненияУдаления(СведенияОРезультатахУдаления);
	КонецЕсли;
	УстановитьМонопольныйРежимНаСервере(Ложь);
	Возврат СведенияОРезультатахУдаления;
	
КонецФункции

// Параметры:
//   СведенияОРезультатахУдаления - см. УдалениеПомеченныхОбъектовСлужебныйКлиентСервер.НовыйСведенияОРезультатахУдаления
//
&НаСервере
Процедура ОбработатьРезультатВыполненияУдаления(СведенияОРезультатахУдаления)
	
	Если НеУдаленные.ПолучитьЭлементы().Количество() > 0 Тогда
		Элементы.СтраницыОтображениеСостояния.ТекущаяСтраница = Элементы.СостояниеЧастичноеУдаление;
		Элементы.НадписьСостояниеЧастичноеУдаление.Заголовок = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru='Удалено %1 из %2.'"),
			СведенияОРезультатахУдаления.УдаленныеКоличество,
	 		СведенияОРезультатахУдаления.НеУдаленныеКоличество + СведенияОРезультатахУдаления.УдаленныеКоличество);
		УстановитьСостояниеНеуспешноеУдалениеСПанельюСостояния();
	ИначеЕсли СведенияОРезультатахУдаления.УдаленныеКоличество > 0 Тогда
		УстановитьСостояниеВыбораПомеченныхНаУдалениеСПанельюСостояния();
		
		Элементы.СтраницыОтображениеСостояния.ТекущаяСтраница = Элементы.СостояниеВыполнено;
		Элементы.ДекорацияПредставлениеЗавершенияУспешно.Заголовок = НСтр("ru='Удаление успешно завершено.'");
	Иначе
		УстановитьСостояниеВыбораПомеченныхНаУдаление();
	КонецЕсли;
	
КонецПроцедуры

// Параметры:
//   РезультатУдаления - Структура:
//   * АдресРезультата - Строка
//   
// Возвращаемое значение:
//   см. УдалениеПомеченныхОбъектовСлужебныйКлиентСервер.НовыйСведенияОРезультатахУдаления
//
&НаСервере
Функция ЗагрузитьРезультатУдаления(РезультатУдаления, ИдентификаторХранилищаРезультата, СведенияОРезультате)
	ОбщийРезультатВыполнения = ПолучитьИзВременногоХранилища(РезультатУдаления.АдресРезультата);
	Если ТипЗнч(ОбщийРезультатВыполнения) = Тип("Структура") Тогда
		РезультатВыполненияВФоне = ОбщийРезультатВыполнения;
	Иначе
		Если ОбщийРезультатВыполнения[0].Статус = "Ошибка" Тогда
			Возврат ОбработатьРезультатУдаленияОшибка(ОбщийРезультатВыполнения[0]);
		КонецЕсли;	
		
		РезультатВыполненияВФоне = ПолучитьИзВременногоХранилища(ОбщийРезультатВыполнения[0].АдресРезультата);
		Для ИндексПорции = 1 По КоличествоПорций - 1 Цикл
			АдресРезультатаПорции = ОбщийРезультатВыполнения[ИндексПорции].АдресРезультата;
			РезультатВыполненияПорцииВФоне = ПолучитьИзВременногоХранилища(АдресРезультатаПорции);
			
			РезультатВыполненияВФоне.КоличествоНеУдаленных = РезультатВыполненияВФоне.КоличествоНеУдаленных
				+ РезультатВыполненияПорцииВФоне.КоличествоНеУдаленных;
			РезультатВыполненияВФоне.КоличествоУдаленных = РезультатВыполненияВФоне.КоличествоУдаленных
				+ РезультатВыполненияПорцииВФоне.КоличествоУдаленных;
			ОбщегоНазначенияКлиентСервер.ДополнитьТаблицу(РезультатВыполненияПорцииВФоне.СвязиНеудаленных,
				РезультатВыполненияВФоне.СвязиНеудаленных);
			ОбщегоНазначенияКлиентСервер.ДополнитьМассив(РезультатВыполненияВФоне.Удаленные,
				РезультатВыполненияПорцииВФоне.Удаленные);
			РезультатВыполненияВФоне.ДеревоПомеченныхНаУдаление =
				ДеревоПомеченныхНаУдалениеБезУдаленных(РезультатВыполненияВФоне.ДеревоПомеченныхНаУдаление,
				РезультатВыполненияПорцииВФоне.Удаленные);
			ОбъединитьПомеченныеНаУдаление(РезультатВыполненияВФоне.ДеревоПомеченныхНаУдаление,
				РезультатВыполненияПорцииВФоне.ДеревоПомеченныхНаУдаление);
			ОбъединитьНеУдаленные(РезультатВыполненияВФоне.НеУдаленные, РезультатВыполненияПорцииВФоне.НеУдаленные);
		КонецЦикла;
		ОбщееКоличествоОбработанных = 0;
		ОбщееКоличествоВыбранных = 0;
		КоличествоПорций = 0;
		ПрогрессУдаления.Очистить();
	КонецЕсли;
	СведенияОРезультате = ?(УдалятьПриОткрытии, СведенияОРезультате, Неопределено);

	Результат = СформироватьРезультатУдаления(СведенияОРезультате, РезультатВыполненияВФоне,
		ИдентификаторХранилищаРезультата);

	Если РезультатВыполненияВФоне <> Неопределено Тогда
		ЗаполнитьКоллекциюЭлементовДереваДанныхФормы(ДеревоПомеченныхНаУдаление,
			РезультатВыполненияВФоне.ДеревоПомеченныхНаУдаление);
		ЗаполнитьКоллекциюЭлементовДереваДанныхФормы(НеУдаленные, РезультатВыполненияВФоне.НеУдаленные);
		СвязиНеудаленных.Загрузить(РезультатВыполненияВФоне.СвязиНеудаленных);
	КонецЕсли;
	Возврат Результат;
КонецФункции

&НаСервереБезКонтекста
Функция ДеревоПомеченныхНаУдалениеБезУдаленных(ПомеченныеНаУдаление, Удаленные)
	
	Результат = ПомеченныеНаУдаление.Скопировать();
	МодифицированныеРодители = Новый Массив;
	
	Для Каждого УдаляемыйСсылка Из Удаленные Цикл
		СтрокаДерева = Результат.Строки.Найти(УдаляемыйСсылка, "УдаляемыйСсылка", Истина);
		Если СтрокаДерева = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		
		Если СтрокаДерева.Родитель <> Неопределено Тогда
			МодифицированныеРодители.Добавить(СтрокаДерева.Родитель);
		КонецЕсли;
		СтрокаДерева.Родитель.Строки.Удалить(СтрокаДерева);
	КонецЦикла;
	
	МодифицированныеРодители = ОбщегоНазначенияКлиентСервер.СвернутьМассив(МодифицированныеРодители);
	
	Для Каждого МодифицированныйРодитель Из МодифицированныеРодители Цикл
		Если МодифицированныйРодитель.Строки.Количество() > 0 Тогда
			Продолжить;
		КонецЕсли;
		
		Результат.Строки.Удалить(МодифицированныйРодитель);
	КонецЦикла;
	
	Возврат Результат;
	
КонецФункции

&НаСервереБезКонтекста
Процедура ОбъединитьПомеченныеНаУдаление(Приемник, Источник)
	
	КоличествоСтрок = Источник.Строки.Количество();
	
	Для ИндексСтроки = 0 По КоличествоСтрок - 1 Цикл
		СтрокаДереваИсточник = Источник.Строки[ИндексСтроки];
		Если СтрокаДереваИсточник.Пометка = 0 Тогда
			Продолжить;
		КонецЕсли;
		
		СтрокаДереваПриемник = Приемник.Строки.Найти(СтрокаДереваИсточник.УдаляемыйСсылка, "УдаляемыйСсылка"); 
		Если СтрокаДереваПриемник  = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		
		СтрокаДереваПриемник.Пометка = СтрокаДереваИсточник.Пометка;
		КоличествоПодстрок = СтрокаДереваИсточник.Строки.Количество();
		Для ИндексПодстроки = 0 По КоличествоПодстрок - 1 Цикл
			
			ПодстрокаДереваИсточник = СтрокаДереваИсточник.Строки[ИндексПодстроки];
			
			ПодстрокаДереваПриемник = СтрокаДереваПриемник.Строки.Найти(ПодстрокаДереваИсточник.УдаляемыйСсылка, "УдаляемыйСсылка");
			Если ПодстрокаДереваПриемник = Неопределено Тогда
				Продолжить;
			КонецЕсли;
			
			ПодстрокаДереваПриемник.Пометка = ПодстрокаДереваИсточник.Пометка;
		КонецЦикла;
	КонецЦикла;
	
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ОбъединитьНеУдаленные(Приемник, Источник)
	
	КоличествоСтрок = Источник.Строки.Количество();
	
	Для Каждого СтрокаДереваИсточник Из Источник.Строки Цикл
		СтрокаДереваПриемник = Приемник.Строки.Добавить();
		ЗаполнитьЗначенияСвойств(СтрокаДереваПриемник, СтрокаДереваИсточник);
		Для Каждого ПодстрокаДереваИсточник Из СтрокаДереваИсточник.Строки Цикл
			ПодстрокаДереваПриемник = СтрокаДереваПриемник.Строки.Добавить();
			ЗаполнитьЗначенияСвойств(ПодстрокаДереваПриемник, ПодстрокаДереваИсточник);
		КонецЦикла;
	КонецЦикла;
	
КонецПроцедуры

&НаСервере
Функция СформироватьРезультатУдаления(СведенияОРезультате, РезультатВыполненияВФоне, ИдентификаторХранилищаРезультата)
	Результат = ?(СведенияОРезультате = Неопределено,
		УдалениеПомеченныхОбъектовСлужебныйКлиентСервер.НовыйСведенияОРезультатахУдаления(),
		СведенияОРезультате);
	
	РезультатПрепятствующиеУдалению = ?(ЭтоАдресВременногоХранилища(Результат.АдресРезультата), 
		ПолучитьИзВременногоХранилища(Результат.АдресРезультата),
		УдалениеПомеченныхОбъектовСлужебный.ПрепятствующиеУдалению());
	
	Если РезультатВыполненияВФоне <> Неопределено Тогда
		ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Результат.Удаленные, РезультатВыполненияВФоне.Удаленные);
		Результат.УдаленныеКоличество = РезультатВыполненияВФоне.КоличествоУдаленных + Результат.УдаленныеКоличество;
		Результат.НеУдаленныеКоличество = РезультатВыполненияВФоне.КоличествоНеУдаленных + Результат.НеУдаленныеКоличество;
		Результат.Успешно = Результат.УдаленныеКоличество > 0 И Результат.НеУдаленныеКоличество = 0;
	
		СвязиНеудаленныхРезультата = УдалениеПомеченныхОбъектовСлужебный.ОбъединениеТаблиц(
				РезультатПрепятствующиеУдалению,
				РезультатВыполненияВФоне.СвязиНеудаленных,
				Истина);
	Иначе
		СвязиНеудаленныхРезультата = РезультатПрепятствующиеУдалению;
	КонецЕсли;

	Результат.АдресРезультата = ПоместитьВоВременноеХранилище(
		СвязиНеудаленныхРезультата, ИдентификаторХранилищаРезультата);
			
	Возврат Результат;		
КонецФункции

#КонецОбласти

#Область ВыполнениеДействий

&НаКлиенте
Процедура ПриВыбореДействияМестаИспользования(Знач ВыбранноеЗначение, Знач ТекущиеДанные)
	
	Если ВыбранноеЗначение = "ЗаменитьСсылку" Тогда
		УстановитьЗаменитьНа(Неопределено);
	ИначеЕсли ВыбранноеЗначение = "Удалить" И НЕ ТекущиеДанные.СсылочногоТипа Тогда
		Состояние(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru='Нельзя установить действие удалить для %1'"),
			ТекущиеДанные.Представление));
	Иначе	
		ЗарегистрироватьДействиеМестаИспользования(ТекущиеДанные, ВыбранноеЗначение);
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура НачатьВыполнениеДополнительнойОбработки(Параметр)
	ПредставлениеОперации = НСтр("ru='Дополнительная обработка мешающих удалению объектов'");
	
	УстановитьСостояниеНеуспешноеУдалениеСПанельюСостояния();
	
	Элементы.СтраницыОтображениеСостояния.ТекущаяСтраница = Элементы.СостояниеВыполняется;
	Элементы.ДекорацияПредставлениеДлительнойОперации.Заголовок = НСтр("ru='Выполняется дополнительная обработка причин неудаления...'");
	Элементы.КоманднаяПанельФормы.Доступность = Ложь;
	Элементы.СтраницыИнформация.ТолькоПросмотр = Истина;
	
		
	Обработчик = Новый ОписаниеОповещения("ПослеЗавершенияВыполненияДополнительнойОбработки", ЭтотОбъект);
	ВыполняемаяОперация = НачатьВыполнениеДополнительнойОбработкиСервер();
	ПриНачалеФоновогоЗадания(Обработчик);
КонецПроцедуры

&НаСервере
Функция НачатьВыполнениеДополнительнойОбработкиСервер()
	ИмяМетода = "УдалениеПомеченныхОбъектовСлужебный.ВыполнитьОбработкуПричинНеудаления";
	
	ПараметрыМетода = ДлительныеОперации.ПараметрыВыполненияФункции(УникальныйИдентификатор);
	ПараметрыМетода.НаименованиеФоновогоЗадания = НСтр("ru = 'Дополнительная обработка мешающих удалению объектов'");
	
	Задание = ДлительныеОперации.ВыполнитьФункцию(ПараметрыМетода, ИмяМетода, ТаблицаДействий.Выгрузить());
	
	Возврат Задание;
КонецФункции

&НаКлиенте
Процедура ПослеЗавершенияВыполненияДополнительнойОбработки(Результат, ДополнительныеПараметры) Экспорт
	Если Результат = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	ВыполняетсяЗадание = Ложь;
	
	Если Результат.Статус = "Ошибка" Тогда
		УстановитьСостояниеНеуспешноеУдалениеСПанельюСостояния();
		ЗаполнитьИнформациюОшибкамиФоновогоЗадания(ЭтотОбъект, Результат);
		УстановитьМонопольныйРежимНаСервере(Ложь);
	КонецЕсли;
	
	ПослеЗавершенияФоновогоЗадания(Результат);
КонецПроцедуры

#КонецОбласти

&НаКлиенте
Процедура ПослеПодтвержденияОтменыЗадания(Ответ, ПараметрыВыполнения) Экспорт
	Если Ответ = КодВозвратаДиалога.Прервать Тогда
		ПоказатьДиалогПередЗакрытием = Ложь;
		ОтменитьОперациюСервер(ВыполняемаяОперация);
		УстановитьМонопольныйРежимНаСервере(Ложь);	
		Закрыть(СведенияОРезультатахУдаления);
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПриОбновленииПрогрессаФоновогоЗадания(Задание, ДополнительныеПараметры) Экспорт
	Если Задание.Прогресс <> Неопределено Тогда
		ПараметрыПрогресса = Неопределено;
		Если Задание.Прогресс.Свойство("ДополнительныеПараметры", ПараметрыПрогресса)
			И ПараметрыПрогресса = "ПрогрессМногопоточногоПроцесса" Тогда
			Возврат;
		КонецЕсли;
		
		Элементы.ПредставлениеПрогресса.Видимость = Истина;
		Если Не ДополнительныеПараметры.ЭтоПроцессУдаления Или ПараметрыПрогресса = Неопределено Тогда
			ТекстПрогресса = Задание.Прогресс.Текст;
		Иначе
			ТекстПрогресса = ТекстПрогресса(ПараметрыПрогресса);
		КонецЕсли;
		Элементы.ПредставлениеПрогресса.Заголовок = ТекстПрогресса;
	КонецЕсли;
КонецПроцедуры

&НаСервере
Функция ТекстПрогресса(ПараметрыПрогресса)
	
	Отбор = Новый Структура;
	Отбор.Вставить("НомерСеанса", ПараметрыПрогресса.НомерСеанса);
	СтрокиТаблицы = ПрогрессУдаления.НайтиСтроки(Отбор);
	Если СтрокиТаблицы.Количество() = 0 Тогда
		СтрокаТаблицы = ПрогрессУдаления.Добавить();
		СтрокаТаблицы.НомерСеанса = ПараметрыПрогресса.НомерСеанса;
		ПредыдущееКоличествоОбработанных = 0;
	Иначе
		СтрокаТаблицы = СтрокиТаблицы[0];
		ПредыдущееКоличествоОбработанных = СтрокаТаблицы.КоличествоОбработанных;
	КонецЕсли;
	СтрокаТаблицы.КоличествоОбработанных = ПараметрыПрогресса.КоличествоОбработанных;
	ОбщееКоличествоОбработанных = ОбщееКоличествоОбработанных
		+ (ПараметрыПрогресса.КоличествоОбработанных - ПредыдущееКоличествоОбработанных);
	
	ТекстПрогресса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Обработано %1 из %2'"),
		ОбщееКоличествоОбработанных,
		ОбщееКоличествоВыбранных);
	Возврат ТекстПрогресса;
	
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ЗначениеПометкиЭлементов(ЭлементыРодителя)
	
	ЕстьПомеченные    = Ложь;
	ЕстьНепомеченные = Ложь;
	
	Для каждого ЭлементРодителя Из ЭлементыРодителя Цикл
		
		Если ЭлементРодителя.Пометка = 0 Тогда
			ЕстьНепомеченные = Истина;
		ИначеЕсли ЭлементРодителя.Пометка = 1 Тогда 	
			ЕстьПомеченные = Истина;
		КонецЕсли;
		
		Если ЕстьНепомеченные И ЕстьПомеченные Тогда
			Прервать;
		КонецЕсли;
		
	КонецЦикла;
	
	Если ЕстьПомеченные Тогда
		Если ЕстьНепомеченные Тогда
			Возврат 2;
		Иначе
			Возврат 1;
		КонецЕсли;
	Иначе
		Возврат 0;
	КонецЕсли;
	
КонецФункции

#КонецОбласти

&НаСервере
Процедура ЗаполнитьКоллекциюЭлементовДереваДанныхФормы(ДанныеФормы, ДеревоЗначений)
	СтрокиДанныхФормы = ДанныеФормы.ПолучитьЭлементы();
	СтрокиДанныхФормы.Очистить();
	ОбщегоНазначения.ЗаполнитьКоллекциюЭлементовДереваДанныхФормы(СтрокиДанныхФормы, ДеревоЗначений);
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Функция ЭтоОшибкаУстановкиМонопольногоРежима(ПодробныйТекстОшибкиФоновогоЗадания)
	ТекстОшибкиМонопольно = НСтр("ru='Ошибка разделенного доступа к базе'");	
	Возврат (СтрНайти(ПодробныйТекстОшибкиФоновогоЗадания,ТекстОшибкиМонопольно) <> 0)
КонецФункции

&НаКлиенте
Функция ОписаниеОперации(ИмяОперации, Параметр = Неопределено)

	Возврат Новый Структура("Имя, Параметр", ИмяОперации, Параметр);

КонецФункции

&НаКлиенте
Процедура ДобавитьЗадание(ИмяОперации, ПараметрЗадания = Неопределено)
	ОчередьЗаданийФормы.Добавить(ОписаниеОперации(ИмяОперации, ПараметрЗадания));
КонецПроцедуры

&НаКлиенте
Функция УдалитьТекущееЗадание()
	ОписаниеЗадания = ОписаниеОперации("");
	
	Если ОчередьЗаданийФормы.Количество() <> 0 Тогда
		ОписаниеЗадания = ОчередьЗаданийФормы[0];
		ОчередьЗаданийФормы.Удалить(0);
	КонецЕсли;
	
	Возврат ОписаниеЗадания.Параметр;
КонецФункции

&НаКлиенте
Функция ТекущееЗадание()
	Возврат ?(ОчередьЗаданийФормы.Количество() = 0, ОписаниеОперации(""), ОчередьЗаданийФормы[0]);
КонецФункции

&НаКлиенте
Процедура ЗапуститьЗаданиеСОжиданием()
	ЗапуститьЗадание();
	ТолькоПросмотр = Ложь;
КонецПроцедуры

&НаКлиенте
Процедура ЗапуститьЗадание(Задание = "", Параметр = Неопределено)
	Результат = Новый Структура("Успешно", Истина);
	
	Если НЕ ПустаяСтрока(Задание) И Задание <> ТекущееЗадание().Имя Тогда
		ДобавитьЗадание(Задание);
	КонецЕсли;
	
	Если ВыполняемаяОперация <> Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	ТекущееЗаданиеФормы = ТекущееЗадание();
	Если НЕ ПустаяСтрока(ТекущееЗаданиеФормы.Имя) Тогда
		
		Если РежимУдаления = "Монопольный" 
				И ТекущееЗаданиеФормы.Имя <> ЗаданияФормы().ПоискПомеченных Тогда
				
			Результат = УстановитьМонопольныйРежимНаСервере(Истина);
			Если НЕ Результат.Успешно Тогда
				Результат.Вставить("Статус", "Ошибка");
				ЗаполнитьИнформациюОшибкамиФоновогоЗадания(ЭтотОбъект, Результат);
				Элементы.СтраницыОтображениеСостояния.Видимость = Истина;
				Элементы.СтраницыОтображениеСостояния.ТекущаяСтраница = Элементы.СостояниеВыполненоСОшибками;
				Возврат;
			КонецЕсли;
		КонецЕсли;	
		
		ВыполняетсяЗадание = Истина;
		
		Если ТекущееЗаданиеФормы.Имя = ЗаданияФормы().УдалениеПомеченных Тогда
			НачатьУдалениеПомеченных(ТекущееЗаданиеФормы.Параметр);
		ИначеЕсли ТекущееЗаданиеФормы.Имя = ЗаданияФормы().ПоискПомеченных Тогда 
			НачатьПоискПомеченных(ТекущееЗаданиеФормы.Параметр);
		ИначеЕсли ТекущееЗаданиеФормы.Имя = ЗаданияФормы().ВыполнениеДополнительнойОбработки Тогда 
			НачатьВыполнениеДополнительнойОбработки(ТекущееЗаданиеФормы.Параметр);
		КонецЕсли;
		
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Функция ЗаданияФормы()
	Задания = Новый Структура;
	Задания.Вставить("УдалениеПомеченных", "УдалениеПомеченных");
	Задания.Вставить("ПоискПомеченных", "ПоискПомеченных");
	Задания.Вставить("ВыполнениеДополнительнойОбработки", "ВыполнениеДополнительнойОбработки");
	Возврат Задания;
КонецФункции

&НаКлиенте
Процедура ОчиститьОчередьЗаданийФормы()
	ОчередьЗаданийФормы.Очистить();
КонецПроцедуры

&НаКлиенте
Функция КоличествоЗаданийВОчереди()
	Возврат  ОчередьЗаданийФормы.Количество();
КонецФункции

#КонецОбласти

#Область Инициализация

СведенияОРезультатахУдаления = УдалениеПомеченныхОбъектовСлужебныйКлиентСервер.НовыйСведенияОРезультатахУдаления(); 
ПредставлениеОперации = "";
ОчередьЗаданийФормы = Новый Массив;

#КонецОбласти